2012-06-30 52 views
4

零或零填充空白时间我写了按小时计算的记录小时查询:分组记录按小时或按天白天和mysql的

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'); 

我需要他们的空白填充零或null。 任何帮助真的很感激。

注意: 在oracle中使用CONNECT BY有一个答案,但我需要在Mysql中的答案,因为Mysql不支持CONNECT BYHere is the link

+0

是否有表'24'记录每天,代表当天的每个小时? –

+0

实际上,它可以有更多的记录。每秒可能有5个或更多记录! – Heidarzadeh

+1

引用问题中'CONNECT BY'和'LEVEL'的唯一目的是生成行。它是Oracle中的一个习惯用语,它应该在Mysql中有相同的功能,它可以做同样的事情。也许这将有助于:http://stackoverflow.com/questions/1806484/generate-many-rows-with-mysql –

回答

1

我创建了一个名为1 TBL_NUMBERS

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

和插入的记录表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

插入更多的记录,如果你有更好的主意,我很想知道;)

+0

不错的选择! – RandomSeed

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'); 

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

+0

谢谢牦牛。这解决了问题,但对于我的用例来说,维护代码有点困难。我找到了另一个解决方案并将其发布到此处。渴望了解你的想法。 – Heidarzadeh