SQL - 包含具有0个聚合结果的行

时间:2014-07-31 15:57:09

标签: sql aggregate-functions

我正在尝试创建遵循模板的每日生产力报告,以便在更新电子表格时无需进行编辑。

SELECT CONVERT(VARCHAR(10), @Start, 101), foo, 
        SUM(CASE WHEN bar BETWEEN @Start AND @End AND bar <> baz THEN 1 ELSE 0 END) AS [bar],
        SUM(CASE WHEN baz BETWEEN @Start AND @End THEN 1 ELSE 0 END) AS [baz]   
FROM table (NOLOCK)
WHERE
    bar BETWEEN @Start AND @End
    and foo IN ('x','y','z')
GROUP BY foo

现在,如果[bar][baz]的聚合值大于0,则会在foo中显示该条目的行。但是,即使foo[bar]都包含零,我也希望[baz]的每个值都有一行。如果没有明确列出foo在其条件中的每个值,这是否可行?


实施例

如果我有桌子

-------------
|foo|bar|baz|
-------------
| x | 1 | 2 |
| x | 2 | 3 |
| y | 2 | 6 |
| y | 3 | 2 |
| z | 9 | 9 |
-------------

@Start = 1@End = 5,我目前获得输出

-------------
|foo|bar|baz|
-------------
| x | 2 | 2 |
| y | 2 | 1 |
-------------

但我想得到

-------------
|foo|bar|baz|
-------------
| x | 2 | 2 |
| y | 2 | 1 |
| z | 0 | 0 |
-------------

1 个答案:

答案 0 :(得分:2)

可能最简单的方法是使用left outer join。假设foo值存在于表中的某个位置,这是一种相当简单的实现方法:

SELECT CONVERT(VARCHAR(10), @Start, 101), f.foo, 
        SUM(CASE WHEN bar BETWEEN @Start AND @End AND bar <> baz THEN 1 ELSE 0 END) AS [bar],
        SUM(CASE WHEN baz BETWEEN @Start AND @End THEN 1 ELSE 0 END) AS [baz]   
FROM (select distinct foo
      from table
      where foo in ('x', 'y', 'z')
     ) f left outer join
     table t (NOLOCK)
     on t.foo = f.foo and t.bar BETWEEN @Start AND @End
GROUP BY f.foo;

如果表中不存在这些值,则可以手动构建它们:

SELECT CONVERT(VARCHAR(10), @Start, 101), f.foo, 
        SUM(CASE WHEN bar BETWEEN @Start AND @End AND bar <> baz THEN 1 ELSE 0 END) AS [bar],
        SUM(CASE WHEN baz BETWEEN @Start AND @End THEN 1 ELSE 0 END) AS [baz]   
FROM (select 'x' as foo union all select 'y' union all select 'z'
     ) f left outer join
     table t (NOLOCK)
     on t.foo = f.foo and t.bar BETWEEN @Start AND @End
GROUP BY f.foo;