Оптимизация SQL-запроса 2.0
Есть примитивная база данных магазина.
Создание (диалект PostgreSQL):
create table customer(
id serial primary key,
name varchar(255),
phone varchar(30),
email varchar(255));
create table product(
id serial primary key,
name varchar(255),
description text,
price integer);
create table cart(
customer_id integer references customer(id),
id serial primary key);
create table cart_product(
cart_id integer references cart(id),
product_id text)
insert into customer(name, phone, email) values
('Василий', '02', '[email protected]'),
('Петр', '04', '[email protected]');
insert into product(name, description, price) values
('IPhone', 'Luxury phone', 100000),
('Apple Watch', 'Cool watches', 50000);
insert into cart(customer_id) values
(1);
insert into cart_product (cart_id, product_id) values
(1, '1, 2');
Таблица cart_product содержит текстовое поле product_id, которое через запятую хранит id таблицы product.
Задача заключается в том, чтобы, объединив таблицы, получить информацию о клиенте и товарах, которые есть в заказе у этого клиента, причем товары должны быть в одном поле, перечисленные через запятую. Вопрос решен (см. листинг ниже), однако совершенно неоптимизированным образом - создаются дублирующиеся строки, которые после добавления product.name схлопываются обратно. Очевидно, что эту задачу можно решить быстрее (с помощью функций и т.п.) - не понимаю, как.
Код (диалект PostgreSQL):
select STRING_AGG(p.name, ', ') as products, cq.cus_name, cq.cus_email, cq.cart_id from
(select
cs.name as cus_name,
cs.email as cus_email,
c.id as cart_id,
unnest(string_to_array(cp.product_id, ', ')) as product_id
from cart_product cp, cart c, customer cs
where c.id = cp.cart_id and
cs.id = c.customer_id) as cq left join product p
on p.id = cq.product_id::integer
group by cq.cus_name, cq.cus_email, cq.cart_id
Результат работы с данными из примера (совпадает с ожидаемым, однако на больших данных считается долго):

