带有交叉表的 PostgreSQL 一对多数据透视表
PostgreSQL one to many pivot with crosstab
我正在尝试在 PostgreSQL
中构建一个查看客户 table、事务 table 的一对多查询,结果是 table 显示客户购买了哪些产品。
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
如果以一种或另一种方式更容易,那并不重要。
我不熟悉交叉表,但是你可以用这样的 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。
忽略没有购买任何东西的客户,因为它更短更快:
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);
详情:
- PostgreSQL Crosstab Query
这里有一个小困难:您需要在查询中添加 boolean
值,因为它不在 table.
中
我正在尝试在 PostgreSQL
中构建一个查看客户 table、事务 table 的一对多查询,结果是 table 显示客户购买了哪些产品。
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
如果以一种或另一种方式更容易,那并不重要。
我不熟悉交叉表,但是你可以用这样的 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。
忽略没有购买任何东西的客户,因为它更短更快:
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);
详情:
- PostgreSQL Crosstab Query
这里有一个小困难:您需要在查询中添加 boolean
值,因为它不在 table.