将行中的 postgresql 查询结果转置为按列值分组

transpose postgresql query result from rows to group by column value

产品Table

INSERT INTO public."Products" ("ID", "Name", "Description") VALUES (1, 'Shirt A', 'Nice to wear');
INSERT INTO public."Products" ("ID", "Name", "Description") VALUES (2, 'Shirt B', 'Looks good');
INSERT INTO public."Products" ("ID", "Name", "Description") VALUES (3, 'Shirt C', 'Light fabric');
INSERT INTO public."Products" ("ID", "Name", "Description") VALUES (4, 'Shirt D', 'Waterproof');

属性Table

INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (1, 'Color', 'Green');
INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (1, 'Color', 'Red');
INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (1, 'Size', 'M');
INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (1, 'Size', 'L');
INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (3, 'Color', 'Green');
INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (4, 'Size', 'L');
INSERT INTO public."Attributes" ("ProductID", "Type", "Value") VALUES (4, 'Size', 'XL');

SQL查询组合结果需要在下面输出

ID, NAME,   Description,   Color,        Size
1, Shirt A, Nice to wear,  [Green, Red], [M, L]
2, Shirt B, Looks good,    null,         null
3, Shirt C, Light fabric,  [Green],      null
4, Shirt D, Waterproof,    null,         [L, XL]

这是一个 join 条件聚合:

select p.*,
       array_agg(a.value) filter (where type = 'Color') as colors,
       array_agg(a.value) filter (where type = 'Size') as sizes
from products p left join
     attributes a
     on p.id = a.productid
group by p.id;

请注意,当您按主键聚合时,Postgres 允许您 select table 的所有列。我假设 idproducts 的主键。

此外,在定义 table 时不要使用双引号。他们只会打乱查询。