我正在尝试在PostgreSQL
中构建一对多查询,查看客户表,交易表,结果是一个表格,显示客户已购买的产品。
table: customers
id
1
2
3
4
5
table: purchases
custid product
1 software 1
1 software 2
3 software 2
3 software 3
4 software 1
5 software 1
5 software 2
5 software 3
我想得到的结果是:
custid software1 software2 software3
1 TRUE TRUE NULL
3 NULL TRUE TRUE
4 TRUE NULL NULL
5 TRUE TRUE TRUE
据我所知,我需要使用crosstab
(因为postgreSQL
并不支持pivot
),但我对snytax不确定。如果输出包含行,我也可以。
custid software1 software2 software3
2 NULL NULL NULL
如果它更容易以某种方式做到这一点,它并不重要。
答案 0 :(得分:2)
忽略那些没有买任何东西的顾客,因为它更短更快:
SELECT * FROM crosstab(
'SELECT custid, product, true FROM purchases ORDER BY 1, 2'
, $$VALUES ('software 1'::text), ('software 2'), ('software 3')$$)
AS ct (custid int, software1 bool, software2 bool, software3 bool);
详细说明:
这里有一个小难点:您需要在查询中添加boolean
值,因为它不在表中。
答案 1 :(得分:1)
我不熟悉交叉表,但你可以使用group by子句和这样的case表达式(只有当只有3个软件时,如果它不受限制,这个解决方案不好):
SELECT t.id,
max(case when s.product = 'software 1' then true end) as software1,
max(case when s.product = 'software 2' then true end) as software2,
max(case when s.product = 'software 3' then true end) as software3
FROM customers t
LEFT OUTER JOIN purchases s ON(t.id = s.custid)
GROUP BY t.id
这还将包含缺失ID的行。