2012-01-04 3 views
1

Я пытаюсь извлечь данные в соответствии с днем ​​недели & также часа дня в том же заявлении (так что я могу видеть, сколько посещений я в час и в течение недели. Вот заявление.MySQL, как заполнить отсутствующие часы/даты в диапазоне?

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] для каждого дня, который будет соответствовать 24-часовой временной шкале st начиная с первого выхода, мне нужно, чтобы отсутствующие были «0».

В то время как я могу обработать его на PHP-конце с помощью циклов, зацикливая его на каждый день недели & внутри этого, на каждый час, довольно утомительно и определенно не чист.

Возможно ли это без временных таблиц (например, включая 24 цифры в самом запросе и т. Д.?)?

ответ

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()) в свой оригинал, чтобы получить данные только для текущей недели.

2

Не знаете, почему вы не хотите использовать временные таблицы, это делает жизнь намного проще.

решения лучше всего выложено здесь: http://www.freeopenbook.com/mysqlcookbook/mysqlckbk-chp-12-sect-10.html

По сути вы должны создать таблицу со всеми часами в день и оставили на ней присоединиться.

+1

Хотя это теоретически может ответить на вопрос, [было бы предпочтительно] (http://meta.stackexchange.com/q/8259) включить сюда основные части ответа и предоставить ссылку для справки. (также: ссылка сломана) – Nanne

Смежные вопросы