PostgreSQL - 如何在此查询中显示count = 0?

时间:2011-07-17 03:24:57

标签: sql postgresql

shelter_inventory(table)

gid | pav_type | yes
 1  |  1       | 1
 2  |  1       | 1
 3  |  0       | 1
 4  |  2       | 1 
 5  |  2       | 0

这是当前查询(不显示count = 0

SELECT pav_type, count(*) FROM shelter_inventory 
WHERE yes = 1 GROUP BY pav_type ORDER BY pav_type

我希望结果显示如下

pav_type | count(*)
 0       |  1
 1       |  2
 2       |  1 
 3       |  0

我怎么能查询这个案子?我使用PostgreSQL。

3 个答案:

答案 0 :(得分:4)

如果您的pav_type值是连续的,那么您可以使用generate_series代替外部表:

select p.pav_type, count(yes)
from generate_series(0,3) as p(pav_type)
left outer join shelter_inventory s
  on p.pav_type = s.pav_type and s.yes = 1
group by p.pav_type
order by p.pav_type

这会产生:

 pav_type | count 
----------+-------
        0 |     1
        1 |     2
        2 |     1
        3 |     0

此:

generate_series(0,3) as p(pav_type)

本质上生成一个内联表,其中包含一个名为pav_type的列和四行:0,1,2,3。您需要在连接条件中使用s.yes = 1(而不是WHERE) )因为您希望yes = 0值位于预先分组的结果集中;如果s.yes = 1在WHERE子句中,那么无论连接条件是什么,都不会计算yes = 0行。

如果您的pav_types不适合generate_series(即不是顺序或步骤顺序)并且您只有少数几个,则可以加入VALUES expression

select p.pav_type, count(yes)
from (values (0), (1), (2), (3)) as p(pav_type)
left outer join shelter_inventory s
  on p.pav_type = s.pav_type and s.yes = 1
group by p.pav_type
order by p.pav_type

您需要确保在正确的位置获得所有括号。

如果您在单独的表中确实有pav_types,那么请对该表执行LEFT OUTER JOIN,而不是使用generate_series。如果您的pav_types不是连续的,并且您有太多不明智地放入VALUES表达式,那么构建一个表来保存有效的pav_type值和LEFT OUTER JOIN。

答案 1 :(得分:0)

您需要一个单独的表,其中包含所有 pav_type值,我们将其命名为pav_type_ref。然后从外部加入。

create table pav_type_ref (pav_type int);
insert into pav_type_ref values (1), (2), (3);

SELECT r.pav_type, sum(case when i.pav_type is null then 0 else 1 end)
FROM pav_type_ref r
left join shelter_inventory i on i.pav_type = r.pav_type
WHERE yes = 1
GROUP BY 1
ORDER BY 1

答案 2 :(得分:0)

使用SUM(CASE WHEN yes=1 THEN 1 ELSE 0 END),您还可以添加GROUP BY pav_type HAVING SUM(CASE WHEN yes=1 THEN 1 ELSE 0 END) = 0