MySQL如何填写范围内缺少的小时/日期?

时间:2012-01-04 10:34:40

标签: mysql gaps-and-islands

我正在尝试根据星期几提取数据&也是同一天的一天中的小时(所以我可以看到我每小时和一周内访问了多少次。这是声明。

SELECT
count(id) as count,
HOUR(created) as hour_of_day,
WEEKDAY(created) as day_of_week,
DATE_FORMAT(created,'%W') name_of_day
FROM visitors
GROUP BY day_of_week,hour_of_day
ORDER BY day_of_week,hour_of_day ASC

一些示例数据

    count   hour_of_day day_of_week name_of_day
    2       0           0           Monday
    1       1           0           Monday
    1       4           0           Monday
    4       5           0           Monday
    1       6           0           Monday
    4       7           0           Monday
    1       9           0           Monday
    1       10          0           Monday
    1       12          0           Monday
    1       13          0           Monday
    2       16          0           Monday
    5       18          0           Monday
    5       19          0           Monday

问题 如您所见,数据中的数据丢失了很多小时。因为我正在创建一个图形,每天需要[x,x,x,x,x,x,x]形式的数据,这些数据将与从第一个输出开始的24小时时间轴相匹配,我需要缺少的是'0'。

虽然我可以在PHP端使用循环处理它,但是为一周中的每一天循环播放它。在这个范围内,每一个小时,都是相当无聊的,绝对不干净。

是否可以不使用临时表(比如在查询中包含24位数字等?)?

2 个答案:

答案 0 :(得分:2)

不是最漂亮的。但如果你真的不能使用临时表,它应该可以做到这一点:

select ifnull(count,0) as count,dh.hour_of_day,
dh.day_of_week,date_format((date('2012-01-02') + interval dh.day_of_week day),'%W') as name_of_day
from
(
select day_of_week,hour_of_day
from 
(
 select 0 as day_of_week union select 1 union select 2 union select 3 
 union select 4 union select 5 union select 6
) d
 join
(
 select 0 as hour_of_day 
 union select 1 union select 2 union select 3 union select 4 
 union select 5 union select 6 union select 7 union select 8
 union select 9 union select 10 union select 11 union select 12
 union select 13 union select 14 union select 15 union select 16
 union select 17 union select 18 union select 19 union select 20
 union select 21 union select 22 union select 23
) h
) dh
left outer join
(
SELECT
count(id) as count,
HOUR(created) as hour_of_day,
WEEKDAY(created) as day_of_week,
DATE_FORMAT(created,'%W') name_of_day
FROM visitors
GROUP BY day_of_week,hour_of_day
) v on dh.day_of_week = v.day_of_week and dh.hour_of_day = v.hour_of_day
ORDER BY dh.day_of_week,dh.hour_of_day ASC; 

虽然小心!如果您在多个星期内运行查询,则会将一周中的多天添加到一起。您可能需要考虑添加“仅本周”谓词。例如,将where yearweek(created) = yearweek(now())添加到原始选择中以获取当前周的数据。

答案 1 :(得分:1)

不确定为什么你不想使用临时表,它会让生活更轻松。

解决方案最好在此处列出:http://www.freeopenbook.com/mysqlcookbook/mysqlckbk-chp-12-sect-10.html

基本上你必须创建一个包含一天中所有小时数的表,并在其上保持联接。