【问题标题】:Group By Date With Empty Groups空组按日期分组
【发布时间】:2009-09-25 15:51:02
【问题描述】:

我有一个 loginAudit 表,我正在尝试获取每天所有登录的计数。我想做的是让没有登录的日子返回他们的日子,登录计数为 0。目前没有登录的日子没有返回任何行。

这可能是不可能的,必须在返回查询结果后填写应用中的空组吗?

  SELECT DATEADD(day, DATEDIFF(day,0,LoginAudit.LoginDateTime), 0) as LoginDate,  
         COUNT(DISTINCT LoginAudit.LoginAuditID) AS Logins  
    FROM LoginAudit 
GROUP BY DATEADD(day, DATEDIFF(day,0,LoginAudit.LoginDateTime), 0)
ORDER BY 1  

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql


    【解决方案1】:

    本质上,您所要求的是将您的表格加入日期“表格”。日期表将没有间隙,您将根据日期值进行分组。那么如何创建日期表呢?

    SQL for Smarties 中,建议您保留一个整数表,以备不时之需。然后,您可以通过将表加入其中来选择所需的任何序列。

    因此,如果您有一个整数表,其中的值根据需要从 NOW() 回溯许多天,您可以执行以下操作:

    SELECT DATE_SUB(CURDATE(), INTERVAL i.intvalue DAY) AS thedate, 
           COUNT(DISTINCT LoginAudit.LoginAuditID) AS logins
    FROM i LEFT JOIN dual ON (DATE_SUB(NOW(), INTERVAL i.intvalue DAY)= day)
    GROUP BY DATE_SUB(CURDATE(), INTERVAL i.intvalue DAY)
    ORDER BY i DESC;
    

    ETA,对于 mysql:

    //创建整数表

    create table i(i integer not null primary key);
    insert into i values (0),(1),(2) ... (9);
    

    如果我需要 0-99 个连续数字:

    SELECT 10*t.i + u.i AS number
      FROM i AS u
    CROSS JOIN 
      i AS t
    ORDER BY number;
    

    如果我需要连续的日期:

    SELECT date_sub(curdate(), interval (10*t.i + u.i) DAY) as thedate 
      FROM i AS u
    CROSS JOIN 
      i AS t
    ORDER BY thedate;
    

    【讨论】:

    • @joon:是的。但尝试它是找出答案的最简单方法。
    • 我做到了,但无法让它工作...... Mysql 似乎在“DUAL”一词上失败了。 (SELECT DATE_SUB(CURDATE(), INTERVAL ints.id DAY) AS thedate, COUNT(DISTINCTwinnings.id) AS 获胜者 FROM ints LEFT JOIN dual ON (DATE_SUB(NOW(), INTERVAL ints.id DAY)= day) GROUP BY DATE_SUB(CURDATE(), INTERVAL ints.id DAY) ORDER BY ints DESC;)
    • @joon:对此感到抱歉。这篇文章很旧,我几乎总是使用 MySQL。
    • 你知道我怎样才能让它工作(我在上面发布的查询)吗?否则我会把它变成一个新问题:)
    • @joon:在我的回答中添加了一些 MySQL 以帮助您入门。
    【解决方案2】:

    我以为我已经相当彻底地搜索了解决方案,但当然在发布我的问题后我发现了这个链接:

    SQL group by day, show orders for each day

    哇!

    【讨论】:

      【解决方案3】:

      您使用的是什么 DBMS?

      如果是 Oracle,您可以尝试在子查询中选择日期,如下所示:

      SELECT TRUNC(SYSDATE) + 1 - LEVEL AS today,
             TRUNC(SYSDATE) + 2 - LEVEL AS tomorrow
      FROM DUAL
      CONNECT BY LEVEL <= 30 /* Last 30 days */
      

      那么你可能会这样做:

      SELECT today as LoginDate,  
             COUNT(DISTINCT LoginAudit.LoginAuditID) AS Logins  
      FROM (
             SELECT TRUNC(SYSDATE) + 1 - LEVEL AS today,
                    TRUNC(SYSDATE) + 2 - LEVEL AS tomorrow
             FROM DUAL
             CONNECT BY LEVEL <= 30 /* Last 30 days */
           ),
           LoginAudit 
      WHERE LoginAudit.LoginDateTime BETWEEN today AND tomorrow
      GROUP BY today
      ORDER BY 1
      

      【讨论】:

      • 不幸的是使用 MS SQL Server 2005。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 2021-06-05
      • 2021-09-30
      • 2012-05-28
      • 2011-12-30
      相关资源
      最近更新 更多