2012-05-24 4 views
11

У меня есть количество сообщений, сохраненных в таблице InnoDB в MySQL. В таблице указаны столбцы «id», «date», «user», «content». Я хотел бы сделать некоторые статистические графики, так что я в конечном итоге, используя следующий запрос, чтобы получить количество сообщений в час вчера:Среднее количество сообщений в час по MySQL?

SELECT HOUR(FROM_UNIXTIME(`date`)) AS `hour`, COUNT(date) from fb_posts 
WHERE DATE(FROM_UNIXTIME(`date`)) = CURDATE() - INTERVAL 1 DAY GROUP BY hour 

Это выводит следующие данные:

table data

I можете отредактировать этот запрос, чтобы получить любой день, который я хочу. Но то, что я хочу сейчас, это СРЕДНИЕ каждого часа каждого дня, так что если на 1-й день в 00 часов у меня 20 сообщений, а на 2-й день в 00 часов у меня 40, я хочу, чтобы выход был «30». Я хотел бы иметь возможность выбирать даты, если это возможно.

Заранее благодарен!

ответ

6

Вы можете использовать подзапрос, чтобы группировать данные по дням/часам, а затем принимать среднее значение по часам по второму запросу.

Вот пример, чтобы дать вам среднее количество по часам в течение последних 7 дней:

select the_hour,avg(the_count) 
from 
(
    select date(from_unixtime(`date`)) as the_day, 
    hour(from_unixtime(`date`)) as the_hour, 
    count(*) as the_count 
    from fb_posts 
    where `date` >= unix_timestamp(current_date() - interval 7 day) 
    and created_on < unix_timestamp(current_date()) 
    group by the_day,the_hour 
) s 
group by the_hour 
+0

Почему вы добавляете «s» после подпрограммы (...)? –

+1

Это псевдоним для подзапроса, который требуется в MySQL, чтобы избежать этой ошибки: «ERROR 1248 (42000): каждая производная таблица должна иметь свой собственный псевдоним». Вы можете быть более подробным с ним, если хотите, и использовать что-то вроде 'sub_query'. –

+0

О, я вижу. Хотя решение Linoff было очень похоже, именно это помогло мне понять SQL намного больше. Благодаря! –

0

агрегировать информацию по дате и времени, а затем взять среднее по часам:

select hour, avg(numposts) 
from (SELECT date(`date`) as day, HOUR(FROM_UNIXTIME(`date`)) AS `hour`, 
      count(*) as numposts 
     from fb_posts 
     WHERE DATE(FROM_UNIXTIME(`date`)) between <date1> and <date2> 
     GROUP BY date(`date`), hour 
    ) d 
group by hour 
order by 1 

Кстати, я предпочитаю в то числе явного распоряжения, поскольку большинство баз данных не заказывают результаты группы от. Mysql - это одна база данных.

+0

Для обеспечения эффективности вы должны применять функции к входным значениям (не столбцу даты) в предложении where вашего подзапроса. –

+0

Кроме того, результаты неявно упорядочиваются группой, поэтому порядок не требуется, если это тот порядок, который вы хотите. –

+2

Это похоже на mysql. ANSI SQL весьма специфичен, что группа по результатам не упорядочена (хотя они часто бывают на практике). Я надеюсь, что mysql достаточно умен, чтобы игнорировать предложение «по порядку», если ему не нужно выполнять работу. –

0
SELECT 
    HOUR(FROM_UNIXTIME(`date`)) AS `hour` 
    , COUNT(`id`) \ COUNT(DISTINCT TO_DAYS(`date`)) AS avgHourlyPostCount 
FROM fb_posts 
WHERE `date` > '2012-01-01' -- your optional date criteria 
GROUP BY hour 

Это дает количество всех должностей, разделенное на количество дней, по часам ,

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