我有一个日志表,其中包含一个名为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那天。
答案 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