Sql 选择计数(*)-如果没有匹配的行,则返回0和分组字段

Sql 选择计数(*)-如果没有匹配的行,则返回0和分组字段,sql,postgresql,count,left-join,aggregate-functions,Sql,Postgresql,Count,Left Join,Aggregate Functions,我有以下疑问: SELECT employee,department,count(*) AS sum FROM items WHERE ((employee = 1 AND department = 2) OR (employee = 3 AND department = 4) OR (employee = 5 AND department = 6) OR ([more conditions with the same structure]))

我有以下疑问:

SELECT employee,department,count(*) AS sum FROM items 
WHERE ((employee = 1 AND department = 2) OR 
      (employee = 3 AND department = 4) OR 
      (employee = 5 AND department = 6) OR 
      ([more conditions with the same structure]))
      AND available = true
GROUP BY employee, department;
如果一对“employee department”没有项目,则查询不返回任何内容。我希望它返回零:

 employee | department | sum 
 ---------+------------+--------
 1        |          2 |      0
 3        |          4 |     12  
 5        |          6 |   1234   
编辑1 正如Matthew PK所解释的,看起来这是不可能的。我错误地认为Postgres可以从WHERE子句中提取缺失的值

编辑2
通过一些技巧,这是可能的。:)感谢欧文·布兰德施泰特

不可能?接受挑战。:)

select employee, department,
    count(
        (employee = 1 and department = 2) or 
        (employee = 3 and department = 4) or 
        (employee = 5 and department = 6) or
        null
    ) as sum
from items
where available = true
group by employee, department;
这将完全满足您的要求。如果
employee
department
不是整数,则转换为匹配类型

@ypercube:count()的每条注释需要位于
项的非空列上,因此我们得到的
0
是不存在的标准,而不是
1

另外,将其他条件拉入
左连接
条件(
i.available
,在本例中),这样就不会排除不存在的条件

演出 在评论中提出其他问题。
这应该表现得很好。对于较长的标准列表,
(左)JOIN
可能是最快的方法

如果需要,请尽快创建一个类似的:


如果
(员工、部门)
应该是
主键
,或者您应该在这两列上有一个
唯一的
约束,这也会起到作用。

基于Erwin的加入建议,这个:


你只想要WHERE子句中的雇员和部门组吗?@FarukSahin,实际上不,可能还有其他子句,但我只想按“雇员”和“部门”分组。更新问题accordingly@FarukSahin,误读了你的评论。在输出中,我只需要分组字段和总和。因此,要限制某些(员工、部门)组的输出,不需要所有(员工、部门)组?我没有看到标记为postgresql。检查这个链接,在那里同样的问题得到了回答:Nice
bool或null
,从未想过这个优雅的解决方案。但是使用
NULLIF((条件),'false')
可能更容易阅读。或者
SUM(当…然后是1或0结束时的情况)
。如果表中不存在给定的“员工部门”对,则该操作无效。查看我对question@Igor一旦你习惯了它(它会很快),你就会欣赏它带来的清洁。这真是太棒了:)接下来的问题——这个查询的性能如何?(桌子会很大)。我可以选择在应用程序中实现所要求的功能level@tokarev:我在回答中添加了一点。是的,但只有在CTE中不存在新的配对时,才会将其添加到表中。@Clodoaldo:这是预期效果。问题中的查询具有其搜索的条件列表。问题不是寻找所有现有组合的完整列表。使用
从项目中选择不同的员工、部门
作为CTE
x
,这将更容易实现。
WITH x(employee, department) AS (
   VALUES
    (1::int, 2::int)
   ,(3, 4)
   ,(5, 6)
    -- ... more combinations
   )
SELECT x.employee, x.department, count(i.employee) AS ct
FROM   x
LEFT   JOIN items i ON i.employee = x.employee
                   AND i.department = x.department
                   AND i.available
GROUP  BY x.employee, x.department;
CREATE INDEX items_some_name_idx ON items (employee, department);
with x(employee, department) as (
   values (1, 2)
   )
select
    coalesce(i.employee, x.employee) as employee,
    coalesce(i.department, x.department) as department,
    count(available or null) as ct
from
    x
    full join
    items i on
        i.employee = x.employee
        and
        i.department = x.department
group by 1, 2
order by employee, department