【问题标题】:SQL Server count message per daySQL Server 每天的消息计数
【发布时间】:2016-06-15 10:48:54
【问题描述】:

我正在使用 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

【问题讨论】:

  • 您将需要一种方法来为丢失的日期生成数据。一种选择是日期表,您可以将其添加到您的架构中。

标签: sql sql-server


【解决方案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】:

    这个问题的正常解决方案是生成所有天的数据,然后使用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;
    

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

    【讨论】:

      【解决方案3】:

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

      前:

      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)
      

      【讨论】:

        猜你喜欢
        • 2018-12-03
        • 1970-01-01
        • 2013-12-15
        • 2022-11-21
        • 2018-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-24
        相关资源
        最近更新 更多