当COUNT(*)为NULL时,在GROUP BY中返回0

时间:2016-09-16 13:37:08

标签: sql count null group-by intersystems-cache

这是我的原始查询:

SELECT
    CAST(IndexedDate as varchar),
    COUNT(*) AS Logins
FROM
    Table
WHERE
    EventType = 'Login'
AND IndexedDate > DATEADD(mm, -1, GETDATE())
GROUP BY
    IndexedDate
ORDER BY
    IndexedDate DESC

这会留下空白,例如:

2016-09-13    41
2016-09-12    31
2016-09-09    15
2016-09-08    36

基于this question,我尝试了以下内容并仍然收到了差距,但最重要的是结果是错误的(数字更高):

SELECT
    CAST(IndexedDate as varchar),
    SUM(Case When COUNT(*) Is Null Then 0 Else COUNT(*)  End) AS Logins
FROM
...

如何让我的结果看起来像这样?

2016-09-13    41
2016-09-12    31
2016-09-11    0
2016-09-10    0
2016-09-09    15
2016-09-08    36

我已经检查了一些其他问题,但它们都涉及加入或其他因素,而不是在我的场景中。

更新

根据评论,我尝试了OUTER JOIN。这个迭代最终成功运行,但结果有点倒退......

SELECT
        CAST(a.IndexedDate as varchar) as dt,
        COUNT(*) AS Logins
FROM 
        (
        SELECT *
        FROM Table
        WHERE IndexedDate > DATEADD(mm, -1, GETDATE())
        AND EventType = 'Login'
        ) a
FULL OUTER JOIN (
        SELECT DISTINCT(IndexedDate)
        FROM Table
        WHERE IndexedDate > DATEADD(mm, -1, GETDATE())
        ) b
ON 
        a.IndexedDate = b.IndexedDate
GROUP BY
        b.IndexedDate
ORDER BY
        b.IndexedDate DESC

结果:

2016-09-13    41
2016-09-12    31
(null)    1
(null)    1
2016-09-09    15
2016-09-08    36

我确认汇总b包含缺少的日期。

2 个答案:

答案 0 :(得分:1)

所以我将编辑中的聚合内容翻转到我的原始帖子,现在它正在工作:

<强>查询

SELECT
        CAST(a.IndexedDate as varchar) as dt,
        COUNT(EventType) AS Logins
FROM 
        (
        SELECT DISTINCT(IndexedDate)
        FROM Table
        WHERE IndexedDate > DATEADD(mm, -1, GETDATE())
        ) a
FULL OUTER JOIN (
        SELECT *
        FROM Table
        WHERE IndexedDate > DATEADD(mm, -1, GETDATE())
        AND EventType = 'Login'
        ) b
ON 
        a.IndexedDate = b.IndexedDate
GROUP BY
        a.IndexedDate
ORDER BY
        a.IndexedDate DESC

<强>结果

2016-09-13    41
2016-09-12    31
2016-09-11    0
2016-09-10    0
2016-09-09    15
2016-09-08    36

请注意,我必须将COUNT(*)替换为COUNT(EventType),以便它不会计算聚合中导致1的日期。

答案 1 :(得分:0)

这适用于(在SQL Server中)

declare @mindt date = (select min(IndexedDate ) from p);
declare @dtrange int = DATEDIFF(day,@mindt,(select max(IndexedDate ) from p));

with MyCte AS
    (select   MyCounter = 0
     UNION ALL
     SELECT   MyCounter + 1
     FROM     MyCte
     where    MyCounter < @dtrange)
select coalesce(IndexedDate , dateadd(d, mycounter, @mindt)) IndexedDate
, count(IndexedDate)
from   MyCte 
left join p
  on dateadd(d,mycounter,@mindt) = p.IndexedDate 
group by coalesce(IndexedDate , dateadd(d, mycounter, @mindt))
option (maxrecursion 0);

我们基本上需要两个主要数字,即开始日期和日期范围。

我们为日期范围内的天数建立一个快速计数器。

然后我们选择日期范围中的每个插槽并指定日期和值,如果没有,我们使用DateAdd创建日期并将0指定为值。

Here is a functional示例