2015-04-16 115 views
1

我有問題要解決。PostgreSQL從兩個表中選擇空值

我有兩個表,制度和文件,他們加入throught文件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 

因爲它con保留空的數據。 在此先感謝。

朱利葉斯·

回答

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 
0

除了agent5566:隨着9.4版本,你可以使用,而不是一個CASE FILTER

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;