带有交叉表的 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.