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。
答案 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