6

我写了一个查询,每小时计算记录:

select TO_CHAR(copied_timestamp, 'YYYY-MM-DD HH24'),count(*) from req group by
TO_CHAR(copied_timestamp, 'YYYY-MM-DD HH24');

结果是:

2012-02-22 13    2280
2012-02-22 15    1250
2012-02-22 16    1245
2012-02-22 19    1258

但我需要这样的结果:

2012-02-22 13    2280
2012-02-22 14    0
2012-02-22 15    1250
2012-02-22 16    1245
2012-02-22 17    0
2012-02-22 18    0
2012-02-22 19    1258

我也有这些按天和月分组的查询!

select TO_CHAR(copied_timestamp, 'YYYY-MM-DD'),count(*)  from req
group by TO_CHAR(copied_timestamp, 'YYYY-MM-DD');

select TO_CHAR(copied_timestamp, 'YYYY-MM'),count(*)  from req
group by TO_CHAR(copied_timestamp, 'YYYY-MM');

我也需要用零或空来填充它们的空白。非常感谢任何帮助。

注意:在 oracle using 中有这个问题的答案,CONNECT BY但我需要 Mysql 中的答案,因为 Mysql 不支持CONNECT BY. 链接在这里

4

2 回答 2

2

生成一个单dates_hours列表,其中包含合理范围内的所有日期和时间(例如,从 1900 到 2200)。然后LEFT JOIN从这个表到你当前的查询。

为了使这项技术正确执行,您可能需要向表中添加一个索引列,其中包含转换后的时间戳(copied_timestamp转换为DATETIME,四舍五入为小时)

SELECT date_hour, count(req.converted_timestamp)
FROM
    dates_hours 
    LEFT JOIN req ON req.converted_timestamp = dates_hours.date_hour
WHERE date_hour
    BETWEEN (SELECT MIN(req.converted_timestamp) FROM req)
    AND (SELECT MAX(req.converted_timestamp) FROM req)
GROUP BY date_hour

要生成dates_hours表格:

CREATE TABLE dates_hours (date_hour DATETIME PRIMARY KEY);

DELIMITER $$$
CREATE PROCEDURE generate_dates_hours (to_date DATETIME)
BEGIN

    DECLARE start_date DATETIME;
    DECLARE inc INT;

    SELECT MAX(date_hour) INTO start_date FROM dates_hours;
    IF start_date IS NULL THEN
        SET start_date = '1900-01-01';
    END IF;
    SET inc = 1;
    WHILE start_date + INTERVAL inc HOUR  <= to_date DO
        INSERT INTO dates_hours VALUE (start_date + INTERVAL inc HOUR);
        SET inc = inc +1;
    END WHILE;

END $$$
DELIMITER ;

CALL generate_dates_hours('2200-01-01');

好的,现在我正在校对自己,我意识到这是一个非常牵强的解决方案。我希望有人想出一个更优雅的。

于 2012-07-02T23:51:52.110 回答
2

我创建了一个名为 TBL_NUMBERS 的表

CREATE TABLE `TBL_NUMBER` (`n` int(11) NOT NULL)

并插入从 1 到 1000 的记录。现在我可以使用此查询生成任何类型的日期范围:

SELECT '2012-06-21' + INTERVAL n-1 [DAY | HOUR | MINUTE] or as dateRange
 FROM TBL_NUMBER
WHERE '2012-06-21' + INTERVAL n-1 [DAY | HOUR | MINUTE] <= '2012-06-23';

然后我可以用我的结果加入这个表来填补日期空白。如果我需要超过 1000 个日期范围,我可以在其中插入更多记录TBL_NUMBER

如果您有更好的主意,我很想知道;)

于 2012-07-03T08:37:55.390 回答