按日期分组与空组

时间:2009-09-25 15:51:02

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

我有一个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  

3 个答案:

答案 0 :(得分:4)

基本上你要问的是将你的桌子加入日期的“表”。日期表没有间隙,您可以对日期值进行分组。那么如何创建一个日期表呢?

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;

答案 1 :(得分:3)

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

SQL group by day, show orders for each day

DOOH!

答案 2 :(得分:0)

您使用的是什么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