我有问题要解决。
我有两个表,机构和文档,它们通过文件owner_id和机构ID加入:
机构
id | name
----+-----
1 | a
2 | b
3 | c
4 | d
和
文件
id | owner | value
----+-------+------
1 | 1 | xxx
2 | 1 | yyy
3 | 1 | yyy
4 | 3 | xxx
5 | 3 | xxx
6 | 4 | yyy
我需要算一下,每个名字有多少个值,这种结果:
name | count(total) | count(xxx) | count(yyy)
------+--------------+------------+------------
a | 3 | 1 | 2
b | 0 | 0 | 0
c | 2 | 2 | 0
d | 1 | 0 | 1
我试过这个问题:
SELECT
a.name,
(a.xxx + b.yyy) as total,
a.xxx,
b.yyy
FROM
(SELECT count(documents.id) as xxx,
institution.name
FROM
documents, institution
WHERE
documents.owner_id = institution.id and
documents.value = 'xxx'
GROUP BY
institution.name) as a,
(SELECT count(documents.id) as yyy,
institution.name
FROM
documents,
institution
WHERE
documents.owner_id = institution.id and
documents.value = 'yyy'
GROUP BY
institution.name) as b
WHERE
a.name = b.name
ORDER BY
a.name
但它只返回那些行,其中xxx和yyy不是epmty,这种:
name | count(total) | count(xxx) | count(yyy)
------+--------------+------------+------------
a | 3 | 1 | 2
我错过了这些行:
name | count(total) | count(xxx) | count(yyy)
------+--------------+------------+------------
b | 0 | 0 | 0
c | 2 | 2 | 0
d | 1 | 0 | 1
因为它包含空数据。 提前谢谢。
朱利
答案 0 :(得分:1)
可以更轻松,尝试此解决方案
SELECT i.name,
COUNT(*) total,
COUNT(CASE d.value WHEN 'xxx' THEN 1 ELSE NULL END) x_cnt,
COUNT(CASE d.value WHEN 'yyy' THEN 1 ELSE NULL END) y_cnt
FROM institution i
LEFT JOIN documents d ON d.owner = i.id
GROUP BY i.name
答案 1 :(得分:0)
除了agent5566:从版本9.4开始,您可以使用FILTER而不是CASE
SELECT institution.name,
COUNT(documents.value) AS cnt_total,
COUNT(documents.value) FILTER(WHERE documents.value = 'xxx') AS cnt_xxx,
COUNT(documents.value) FILTER(WHERE documents.value = 'yyy') AS cnt_yyy
FROM institution
LEFT JOIN documents ON documents.owner = institution.id
GROUP BY
institution.name
ORDER BY
institution.name;