我正在使用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
答案 0 :(得分:1)
此问题的常规解决方案是生成所有日期的数据,然后使用left join
。您可以通过多种方式生成日期:
在某些情况下,有一种更简单的解决方案,即条件聚合。这假定每天至少有一条记录。然后,您可以使用条件聚合来实现此目的:
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-01
到2014-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)