Php MySQL分组方式和填充空行

Php MySQL分组方式和填充空行,php,mysql,Php,Mysql,我相信这个问题以前已经得到了回答,但我找不到我需要的细节 对于一个分析系统,我需要能够对行进行分组,并在图表上返回它们,可以按分钟、小时、天、月或年进行分组。我已经正确地工作了(下面的示例代码) 选择计数(不同的用户id)、`hour`、`timestamp` 从跟踪请求 其中site_id='3' 和“时间戳”'2011-08-29 22:00:00' 按“小时”、“日”、“月”、“年”分组 按“时间戳”订购ASC 问题是,像大多数图表一样,我需要填补数据不存在的空白(例如,过去3分钟没有行

我相信这个问题以前已经得到了回答,但我找不到我需要的细节

对于一个分析系统,我需要能够对行进行分组,并在图表上返回它们,可以按分钟、小时、天、月或年进行分组。我已经正确地工作了(下面的示例代码)

选择计数(不同的用户id)、`hour`、`timestamp`
从跟踪请求
其中site_id='3'
和“时间戳”<'2011-08-3104:05:45'
和“时间戳”>'2011-08-29 22:00:00'
按“小时”、“日”、“月”、“年”分组
按“时间戳”订购ASC
问题是,像大多数图表一样,我需要填补数据不存在的空白(例如,过去3分钟没有行)。我读过关于创建“日历表”并连接这些数据的内容,但我如何才能对每个刻度有效地执行此操作(例如,年比分钟容易得多,因为分钟需要表中的许多行)?如果有帮助的话,表中每个都有一列(如上图所示,您可以看到有“小时”、“天”等)

编辑:


最后,我使用PHP通过使用一个空数组并填充它来实现这一点。如果有人能想到一个全(或大部分)SQL解决方案,那就更棒了。

这通常是在数据仓库中通过使用包含所有可能日期列表的日期维度来完成的。对日期维度进行外部联接,并将空值合并为0。

在这个答案中,我将概述如何生成日历表

为天、小时和分钟创建三个表:

CREATE TABLE days (
  day DATE,
  PRIMARY KEY (day)
) 
CREATE TABLE hours (
  hour INT,
  PRIMARY KEY (hour)
) 
CREATE TABLE minutes (
  minute INT,
  PRIMARY KEY (minute)
) 
用0到23的数字填写小时表,用0到59的数字填写分钟表。要填写天数表,可以创建如下过程:

CREATE PROCEDURE make_days(IN start_date DATE, IN end_date DATE)
BEGIN
  DECLARE curr_date DATE;
  SET curr_date = start_date;
  WHILE curr_date <= end_date DO
    INSERT IGNORE INTO days(day)  VALUES(curr_date);
    SET curr_date = DATE_ADD(curr_date, INTERVAL 1 DAY);
  END WHILE;
END
SELECT YEAR(day) AS year, MONTH(day) AS month, DAYOFMONTH(day) AS day, hour, minute
FROM days, hours, minutes
WHERE CAST(CONCAT(day,' ',hour,':',minute) AS DATETIME) BETWEEN '2011-08-31 22:00' AND '2011-09-01 10:00'
ORDER BY year, month, day, hour, minute
现在,您可以使用类似以下的查询为给定时间间隔内的每分钟创建值:

CREATE PROCEDURE make_days(IN start_date DATE, IN end_date DATE)
BEGIN
  DECLARE curr_date DATE;
  SET curr_date = start_date;
  WHILE curr_date <= end_date DO
    INSERT IGNORE INTO days(day)  VALUES(curr_date);
    SET curr_date = DATE_ADD(curr_date, INTERVAL 1 DAY);
  END WHILE;
END
SELECT YEAR(day) AS year, MONTH(day) AS month, DAYOFMONTH(day) AS day, hour, minute
FROM days, hours, minutes
WHERE CAST(CONCAT(day,' ',hour,':',minute) AS DATETIME) BETWEEN '2011-08-31 22:00' AND '2011-09-01 10:00'
ORDER BY year, month, day, hour, minute

在没有数据的情况下,“填补空白”是没有意义的。不管怎样,您的绘图工具/API/任何东西都应该能够生成图表。如果不能,我建议你再找一个。你要找的是所谓的“插值”:@NullUserException,这完全没有帮助。如果出于任何原因,我只是将这些值按顺序排列,并在图表上显示最后30天,我需要填充这些值,而不提供图形“实用工具”日期/时间。>丹尼尔·佩雷拉谢谢你,尽管那篇文章没有解释如何为这种情况制作一个有效的日历表。@Coolist我不明白。所以你有顺序排列的值,但你不知道它们的日期是什么?@NullUserException否,我有日期,但图表不能只显示“8月10-5视图”、“8月12-6视图”、“8月15-2视图”。它需要返回两个视图之间的日期(例如“8月10日至5日视图”、“8月11日至0日视图”、“8月12日至6日视图”)等)。如果您问为什么图形工具不同时获取日期和值,然后自动填充间隙,它需要x(值)和y(日期)数据。谢谢,这非常有用,并且解释得很好。我假设你必须每隔一段时间填写一天,这样表格就不会用完,从一开始填写到一个遥远的日期会更好吗?我最近发现自己正在调试一个我10年前创建的网站,因为当时我想:“当然5位数字就足够了!”。事实证明,在代码中设置任意限制是个坏主意。但我相信,如果你只插入未来15年的所有天数,你会没事的;)这似乎是一个有趣的解决方案。尽管看起来,如果用户对数据库具有只读访问权限,此解决方案不起作用。我想知道是否还有其他方法可以这样做?