将相同的表连接两次以用于不同列中的计数

Ami*_*nli 9 sql postgresql

我有2张桌子

A
+----+-------+
| Id | User  |
+----+-------+
|  1 | user1 |
|  2 | user2 |
|  3 | user3 |
+----+-------+

B
+----+--------+------+
| Id | UserId | Type |
+----+--------+------+
|  1 |      1 | A    |
|  2 |      1 | B    |
|  3 |      1 | C    |
|  4 |      2 | A    |
|  5 |      2 | B    |
|  6 |      2 | C    |
|  7 |      3 | A    |
|  8 |      3 | C    |
+----+--------+------+

UserId is FK from table A.Id
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用单个SQL查询来计算每种类型和类型排列,如下所示.(例如,计数A ^ B表示具有类型A和B的用户数)

+---------+---------+---------+-----------+-----------+-----------+-------------+
| Count A | Count B | Count C | Count A^B | Count A^C | Count B^C | Count A^B^C |
+---------+---------+---------+-----------+-----------+-----------+-------------+
|       3 |       2 |       3 |         2 |         3 |         2 |           2 |
+---------+---------+---------+-----------+-----------+-----------+-------------+
Run Code Online (Sandbox Code Playgroud)

或者对每个排列计数单独查询.

我尝试在下面查询分别计算A和B类型,但它不起作用.

SELECT count(b1.type) AS count_a, count(b2.type) AS count_b FROM A 
JOIN B on A.id = B.user_id
WHERE b1.type = 'A' or b2.type = 'B' 
GROUP BY A.id;

+---------+---------+
| Count A | Count B |
+---------+---------+
|       3 |       2 |
+---------+---------+
Run Code Online (Sandbox Code Playgroud)

rua*_*akh 7

你可以写:

select count(case when "Types" @> array['A'] then 1 end) as "COUNT A",
       count(case when "Types" @> array['B'] then 1 end) as "COUNT B",
       count(case when "Types" @> array['C'] then 1 end) as "COUNT C",
       count(case when "Types" @> array['A','B'] then 1 end) as "COUNT A^B",
       count(case when "Types" @> array['A','C'] then 1 end) as "COUNT A^C",
       count(case when "Types" @> array['B','C'] then 1 end) as "COUNT B^C",
       count(case when "Types" @> array['A','B','C'] then 1 end) as "COUNT A^B^C"
  from ( select array_agg("Type"::text) as "Types"
           from "B"
          group by "UserId"
       ) t
;
Run Code Online (Sandbox Code Playgroud)

我们的想法是,首先我们使用一个子查询,为每个用户生成一个包含他/她类型的数组; 然后外部查询只计算包含每组类型的数组.

您可以在http://sqlfiddle.com/#!15/cbb45/1上看到它的实际效果.(我还在其中包含了子查询的修改版本,以帮助您了解它是如何工作的.)

一些相关的PostreSQL文档: