每天SQL Server计数消息

时间:2016-06-15 10:48:54

标签: sql sql-server

我正在使用SQL Server,我有下表:

tbl_Message:
id, date, group_id

这是一个包含消息的表:它的id,发送日期,发送的组。 我正在尝试计算每天收到的邮件数量。我对它进行了查询,但它没有返回没有消息的日子。查询是:

SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) AS dateDay,
COUNT(*) AS countMsgDay
FROM tbl_Message
WHERE group_id = 1
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0)

示例:

对于tbl_Message

id |     date                 | group_id
----------------------------------------
1  | 2014-10-01 21:04:00.000  | 1
2  | 2014-10-03 21:09:00.000  | 1

查询返回:

dateDay                    | countMsgDay
---------------------------------
2014-10-01 00:00:00.000    | 1
2014-10-03 00:00:00.000    | 1

我想要的是:

dateDay                    | countMsgDay
---------------------------------
2014-10-01 00:00:00.000    | 1
2014-10-02 00:00:00.000    | 0
2014-10-03 00:00:00.000    | 1

3 个答案:

答案 0 :(得分:1)

此问题的常规解决方案是生成所有日期的数据,然后使用left join。您可以通过多种方式生成日期:

  • 使用日历表。
  • 使用递归CTE。
  • 使用数字表。
  • 明确地在查询中包含日期。

在某些情况下,有一种更简单的解决方案,即条件聚合。这假定每天至少有一条记录。然后,您可以使用条件聚合来实现此目的:

SELECT CAST(date as DATE) as dateDay,
       SUM(CASE WHEN group_id = 1 THEN 1 ELSE 0 END) as countMsgDay
FROM tbl_Message
GROUP BY CAST(date as DATE)
ORDER BY dateDay;

这对您有用,假设每天在表格中至少有一条记录

答案 1 :(得分:1)

使用此链接生成您指定日期之间的日期。将start_date用作min(dateDay),将end_date用作max(dateDay)

How to list all dates between two dates

现在使用此表并加入您的查询。说表派生表是dateRange。因此select * from dateRange会生成从2014-10-012014-10-03的日期。

现在使用如下所示的查询来获得所需的输出

select dr.dateval,t.countMsgDay
from dateRange dr
left join
(
    SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) AS dateDay,
    COUNT(*) AS countMsgDay
    FROM tbl_Message
    WHERE group_id = 1
    GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0)
) t
on dr.dateval=t.dateDay

答案 2 :(得分:1)

您需要一个日历表,一旦有了这个日历表,您需要做的就是使用此表的左连接来获取所有日期。除此之外还有许多use cases to calendar table

EX:

select 
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0) AS dateDay,
COUNT(*) AS countMsgDay
from 
Calendar c
left join
yourtable t
on t.date=c.date
and group_id = 1
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, date)/1440 * 1440,0)