Reputation: 73
I have problem to solve.
I have two tables, institutions and documents, they joins throught documents owner_id and institution id:
institution
id | name
----+-----
1 | a
2 | b
3 | c
4 | d
and
documents
id | owner | value
----+-------+------
1 | 1 | xxx
2 | 1 | yyy
3 | 1 | yyy
4 | 3 | xxx
5 | 3 | xxx
6 | 4 | yyy
And I need to count, how many values has each name, this kind of result:
name | count(total) | count(xxx) | count(yyy)
------+--------------+------------+------------
a | 3 | 1 | 2
b | 0 | 0 | 0
c | 2 | 2 | 0
d | 1 | 0 | 1
I have tried this query:
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
But it returns only those rows, where xxx and yyy is not epmty, this kind of:
name | count(total) | count(xxx) | count(yyy)
------+--------------+------------+------------
a | 3 | 1 | 2
I'm missing these rows:
name | count(total) | count(xxx) | count(yyy)
------+--------------+------------+------------
b | 0 | 0 | 0
c | 2 | 2 | 0
d | 1 | 0 | 1
because it contains empty data. Thanks in advance.
Julius
Upvotes: 1
Views: 81
Reputation: 127476
In addition to agent5566: As of version 9.4 you could use FILTER instead of a 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;
Upvotes: 0
Reputation: 1898
It can be easier, try this solution
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
Upvotes: 1