1

可能重复:
如何在 mysql 中生成行生成器
generate_series 等效于 mysql

我在创建 mysql 查询时遇到了麻烦。

我的 PHP 脚本在每次运行时执行此查询: INSERT INTO Executes SET UserIp='%s' (%s is user IP)

执行表是:

ExecuteId UNSIGNED BIGINT AI PRIMARY 
Date TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX 
UserIp CHAR(24) ... | Some Columns

我想每小时检索一次执行次数。最明显的解决方案是:

SELECT COUNT(*) as ExecutesNum, DATE(Date) as D, HOUR(Date) as H GROUP BY D, H

它可以工作,但它不会在没有执行的几个小时内创建行。

我应该修改什么以获得如下结果:

  1 | 2012-09-01 | 14

**0 | 2012-09-01 | 15**

 11 | 2012-09-01 | 16

  1 | 2012-09-01 | 17
4

1 回答 1

2

这是一个相当普遍的问题,我通常通过创建一个包含所有时间的临时表来解决,如下所示:

DROP TABLE IF EXISTS hours;
CREATE TABLE hours (hour VARCHAR(13) PRIMARY KEY);
DROP PROCEDURE IF EXISTS fill_hours;

DELIMITER |
CREATE PROCEDURE fill_hours(start_time DATETIME, end_time DATETIME)
BEGIN
  DECLARE crt_time DATETIME;
  SET crt_time=DATE_SUB(start_time, INTERVAL DATE_FORMAT(start_time, '%i:%s') MINUTE_SECOND);
  WHILE crt_time < end_time DO
    INSERT INTO hours VALUES(DATE_FORMAT(crt_time, '%Y-%m-%d-%H'));
    SET crt_time = DATE_ADD(crt_time, INTERVAL 1 HOUR);
  END WHILE;
END |

CALL fill_hours( (SELECT MIN(Date) FROM Executes), (SELECT MAX(Date) FROM Executes) );

然后,您可以将此表连接到原始表以获得您想要的:

SELECT
h.hour,
COUNT(e.ExecuteId)
FROM hours h
LEFT JOIN Executes e ON DATE_FORMAT(e.Date, "%Y-%m-%d-%H") = h.hour
GROUP BY h.hour
于 2012-09-09T15:50:15.317 回答