7

我有以下查询:

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

有一些技巧是可以的。:) 感谢欧文·布兰德施泰特!

4

3 回答 3

7

不可能?接受挑战。:)

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;

这将为您提供您所要求的确切信息。如果employee并且department不是整数,则强制转换为匹配类型。

根据@ypercube 的评论:count() 需要位于 的非空列上items,因此我们得到0的是不存在的标准,而不是1

此外,将附加条件拉到LEFT JOIN条件中(i.available在本例中),这样您就不会排除不存在的条件。

表现

在评论中解决其他问题。
这应该表现得非常好。对于更长的标准列表,(LEFT) JOIN可能是最快的方法。

如果您需要尽快使用它,请务必创建一个多列索引,例如:

CREATE INDEX items_some_name_idx ON items (employee, department);

If (employee, department)should be the PRIMARY KEY or you should have a UNIQUEconstraint on the two columns, 这也可以解决问题。

于 2012-12-10T16:21:03.287 回答
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;
于 2012-12-10T14:58:39.953 回答
2

基于 Erwin 的加入建议,这个确实有效

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
于 2012-12-10T17:17:55.380 回答