MySQL GROUP BY с несколькими параметрами, скрывающими нули - PullRequest
1 голос
/ 22 декабря 2011

Я читал подобные вопросы здесь о stackoverflow, но структура таблицы OP никогда не бывает такой же, как у меня, поэтому ответ не работает для меня.Посты, которые я прочитал, пытаются группировать один столбец, а не два.Я использую MySQL, последний стабильный выпуск.

Вот моя таблица "reference":

id    formatID    referenceTime
1     1           2011-6-12 12:40
2     2           2011-6-12 1:04
3     4           2011-6-12 1:03
4     2           2011-6-12 15:20
5     3           2011-6-12 9:30
6     3           2011-6-12 2:55
7     5           2011-6-12 13:15
8     1           2011-6-12 12:32
(etc)

Я хочу создать запрос, который показывает, сколько форматов каждого типа встречается по часам дня.Смысл этого в том, чтобы увидеть, какое время года самое загруженное.Я пытаюсь написать запрос, который создаст вывод, который я смогу использовать для некоторых простых веб-приложений с графиками (Highcharts.js).Я хочу, чтобы это выглядело так:

Timeofday  Subgroup  Count
12AM       1         2
12AM       2         6
12AM       3         7
12AM       4         2
12AM       5         0
1AM        1         3
1AM        2         3
1AM        3         0
1AM        4         0
1AM        5         1
(etc)

Я использую этот запрос:

SELECT date_format(referenceTime,'%I %p') AS timeofday,
  reference.referenceFormatID AS subgroup,
  count(*) AS count
FROM reference
GROUP BY timeofday,subgroup ASC

Тем не менее, выходные данные пропускают «строки», где количество равно нулю, и в итоге получается так:

Timeofday  Subgroup  Count
12AM       1         2
12AM       2         6
1AM        3         7
1AM        4         2
1AM        5         1
3AM        1         3
6AM        2         3
7AM        3         1
7AM        4         1
9AM        5         1
(etc)

Мне нужны эти нули, чтобы иметь возможность создать правильно отформатированный ряд данных для моего приложения.

Метод LEFT JOIN, когда вы все время помещаете во вторую таблицу, мне не подходит, потому что я группируюсь по двум различным столбцам.Очевидно, критерии LEFT JOIN удовлетворяются до тех пор, пока каждый час показывает где-то в выходной таблице, но мне нужно каждый час, чтобы появилось каждый формат.

Есть предложения?

1 Ответ

2 голосов
/ 22 декабря 2011

У вас есть два варианта: либо создать таблицу поиска с указанием возможных часов, либо использовать странный запрос, включающий двойную таблицу и объединение, чтобы получить искомые значения.

В первом случае, у вас будет таблица с, может быть, одним полем на данный момент, давайте просто назовем ее часами, а это поле timeofday.

В часах timeofday у вас будут следующие данные:

timeofday
12AM
1AM
2AM
....

Тогда ваш запрос так же прост, как

SELECT hours.timeofday, 
  reference.referenceFormatID AS subgroup,
  count(reference.referenceFormatID) AS count
FROM hours
 LEFT JOIN reference on date_format(referenceTime,'%I %p') = hours.timeofday
GROUP BY hours.timeofday,subgroup ASC

РЕДАКТИРОВАТЬ

Чтобы получить все комбинации, вам также понадобится таблица форматов со всеми возможными идентификаторами формата, какбыл упомянут rfausak.Вы также можете сделать это с отдельным отчетом, но давайте просто предположим, что у вас есть эта таблица, назовем ее форматами.Опять же, эта таблица может иметь один столбец.

Часть 1 предназначена для получения всех комбинаций:

SELECT hours.timeofday, 
       formats.ID
from hours
join formats

Это декартово объединение, которое объединит все возможные часы и идентификаторы формата.

Теперь мы добавляем в LEFT JOIN

SELECT hours.timeofday, 
       formats.ID,
       count(reference.subgroup)
FROM hours
JOIN formats
LEFT JOIN reference on date_format(referenceTime,'%I %p') = hours.timeofday
     AND reference.subgroup  = formats.ID
GROUP BY hours.timeofday,formats.ID ASC

Если вы попытаетесь сделать это с помощью поиска в DUAL таблице, вы можете использовать метод, аналогичный генерации дней из диапазона дат

...