Транспонирование строк в столбцы с группировкой

Есть таблица в postgresql, в каждой строке которой наименование товара и название магазина. Нужно превратить название магазина в столбец и заполнить его товарами из этого магазина. Проблема в том, что названий магазинов очень много и каждый раз лопатить список для "case when Stock = " очень трудозатратно.

Сейчас:

#Item           #Stock
карандаш1       Венера
ручка1          Венера
маркер1         Сатурн
маркер2         Сатурн
маркер3         Сатурн
карандаш1       Сатурн
карандаш1       Плутон
карандаш2       Плутон
ручка1          Марс
ручка2          Марс

Нужно:

#Венера     #Сатурн     #Плутон     #Марс
карандаш1   маркер1     карандаш1   ручка1
ручка1      маркер2     карандаш2   ручка2
            маркер3
            карандаш1

Буду благодарен за любую помощь.


Ответы (1 шт):

Автор решения: Ainar-G

SELECT работает только с константным количеством строк, так что чтобы не писав запрос вручную вывести всё ровно в таком формате как у вас понадобится составить запрос динамически на стороне приложения.

Есть две альтернативы. Если вы делаете запрос для машины, и она умеет читать SQL-массивы, то можете использовать ARRAY_AGG:

SELECT stock, ARRAY_AGG(item) FROM t_1 GROUP BY stock;
 stock  |              array_agg              
--------+-------------------------------------
 Венера | {карандаш1,ручка1}
 Плутон | {карандаш1,карандаш2}
 Сатурн | {маркер1,маркер2,маркер3,карандаш1}
 Марс   | {ручка1,ручка2}
(4 rows)

Если же это какой-то отчёт, который напрямую выводится человеку, можете использовать STRING_AGG:

SELECT stock, STRING_AGG(item, E'\n') FROM t_1 GROUP BY stock;
 stock  | string_agg 
--------+------------
 Венера | карандаш1 +
        | ручка1
 Плутон | карандаш1 +
        | карандаш2
 Сатурн | маркер1   +
        | маркер2   +
        | маркер3   +
        | карандаш1
 Марс   | ручка1    +
        | ручка2
(4 rows)
→ Ссылка