按天分组仍然显示没有行的天数?

时间:2011-02-04 19:53:02

标签: mysql

我有一个日志表,其中包含一个名为logTime的日期字段。我需要显示日期范围内的行数和每天的记录数。问题是我仍然希望显示没有记录的日子。

是否可以仅使用SQL执行此操作?

示例:

SELECT logTime, COUNT(*) FROM logs WHERE logTime >= '2011-02-01' AND logTime <= '2011-02-04' GROUP BY DATE(logTime);

它返回如下内容:

+---------------------+----------+
| logTime             | COUNT(*) |
+---------------------+----------+
| 2011-02-01          |        2 |
| 2011-02-02          |        1 |
| 2011-02-04          |        5 |
+---------------------+----------+
3 rows in set (0,00 sec)

我也想展示2011-02-03那天。

4 个答案:

答案 0 :(得分:5)

为了实现这一点,你需要有一个表(或派生表),它包含你可以使用LEFT JOIN加入的日期。

SQL运用数学集的概念,如果你没有一组数据,就没有什么可以选择。

如果您想了解更多详情,请相应评论。

答案 1 :(得分:5)

MySQL不会为你创建行,所以如果不存在数据,它们自然不会显示。

您可以创建一个日历表,并加入其中,

create table calendar (
    day date primary key,
);

在此表中填入日期(很容易使用存储过程,或者只是一些通用脚本),直到2038年左右,其他一些东西可能会破坏unitl成为问题。

您的查询就变成了例如。

SELECT logTime, COUNT(*) 
  FROM calendar cal left join logs l on cal.day = l.logTime 
WHERE day >= '2011-02-01' AND day <= '2011-02-04' GROUP BY day;

现在,您可以使用其他列来扩展日历表,这些列会告诉您月,年,周等,以便您可以轻松生成其他时间单位的统计信息。 (纯粹主义者可能认为日历表会有一个id整数主键,日志表引用而不是日期)

答案 2 :(得分:0)

我不确定这是否应该由SQL解决。正如其他人所示,这需要维护第二个表,其中包含给定时间跨度的各个日期的 all ,每当时间跨度增长时必须更新(如果时间跨度增长,则必须更新)该时间跨度是当前时间。

相反,您应该使用检查查询的结果并根据需要注入日期。它完全是动态的,不需要中间表。由于您没有指定语言,因此这里是伪代码:

EXECUTE QUERY `SELECT logTime, COUNT(*) FROM logs WHERE logTime >= '2011-02-01' AND logTime <= '2011-02-04' GROUP BY DATE(logTime);`

FOREACH row IN query result
  WHILE (date in next row) - (date in this row) > 1 day THEN
    CREATE new row with date = `date in this row + 1 day`, count = `0`
    INSERT new row IN query result AFTER this row
    ADVANCE LOOP INDEX TO new row (`this row` is now the `new row`)
  END WHILE
END FOREACH

或类似的东西

答案 3 :(得分:0)

DECLARE @TOTALCount INT
DECLARE @FromDate DateTime = GetDate() - 5
DECLARE @ToDate DateTime = GetDate()

SET @FromDate = DATEADD(DAY,-1,@FromDate)
Select  @TOTALCount= DATEDIFF(DD,@FromDate,@ToDate);

WITH d AS 
        (
          SELECT top (@TOTALCount) AllDays = DATEADD(DAY, ROW_NUMBER() 
            OVER (ORDER BY object_id), REPLACE(@FromDate,'-',''))
          FROM sys.all_objects
        )
SELECT AllDays From d