MySQL: заполнение пустых полей нулями при использовании GROUP BY - PullRequest
9 голосов
/ 19 марта 2010

У меня есть таблица MySQL

CREATE TABLE cms_webstat (
    ID int NOT NULL auto_increment PRIMARY KEY,
    TIMESTAMP_X timestamp DEFAULT CURRENT_TIMESTAMP,
    # ... some other fields ...
)

, которая содержит статистику о посетителях сайта.
Для получения посещений в час я использую

SELECT
    hour(TIMESTAMP_X) as HOUR
    , count(*) AS HOUR_STAT
FROM cms_webstat
GROUP BY HOUR
ORDER BY HOUR DESC

, что дает мне

| HOUR | HOUR_STAT |
|  24  |    15     |
|  23  |    12     |
|  22  |    9      |
|  20  |    3      |
|  18  |    2      |
|  15  |    1      |
|  12  |    3      |
|   9  |    1      |
|   3  |    5      |
|   2  |    7      |
|   1  |    9      |
|   0  |    12     |

И я бы хотел получить следующее:

| HOUR | HOUR_STAT |
|  24  |    15     |
|  23  |    12     |
|  22  |    9      |
|  21  |    0      |
|  20  |    3      |
|  19  |    0      |
|  18  |    2      |
|  17  |    0      |
|  16  |    0      |
|  15  |    1      |
|  14  |    0      |
|  13  |    0      |
|  12  |    3      |
|  11  |    0      |
|  10  |    0      |
|   9  |    1      |
|   8  |    0      |
|   7  |    0      |
|   6  |    0      |
|   5  |    0      |
|   4  |    0      |
|   3  |    5      |
|   2  |    7      |
|   1  |    9      |
|   0  |    12     |

Как мне изменить запрос, чтобы получить такой результат (с одним запросом MySQL, без создания временных таблиц)? Можно ли получить такой результат одним запросом MySQL?

Ответы [ 4 ]

8 голосов
/ 19 марта 2010

Создать другую таблицу с одним столбцом,

CREATE TABLE hours_list (
    hour int NOT NULL PRIMARY KEY
)

Заполните все 24 часа.

Затем выполните объединение в этой таблице, чтобы заполнить нули.

SELECT
    hs.hour as HOUR, COUNT(ws.ID) AS HOUR_STAT
FROM hours_list hs 
LEFT JOIN cms_webstat ws ON hs.hour = hour(ws.TIMESTAMP_X)
GROUP BY hs.hour
ORDER BY hs.hour DESC
4 голосов
/ 13 октября 2010

Я наконец нашел ответ. Может быть, я безумен, но это работает.

SELECT HOUR, <b>max</b>(HOUR_STAT) as HOUR_STAT FROM (
    (
        SELECT HOUR(TIMESTAMP_X) as HOUR, count(*) as HOUR_STAT
        FROM cms_webstat
        WHERE date(TIMESTAMP_X) = date(now())
    )
    UNION (SELECT 0 as HOUR, 0)
    UNION (SELECT 1 as HOUR, 0)
    UNION (SELECT 2 as HOUR, 0)
    UNION (SELECT 3 as HOUR, 0)
    UNION (SELECT 4 as HOUR, 0)
    UNION (SELECT 5 as HOUR, 0)
    UNION (SELECT 6 as HOUR, 0)
    UNION (SELECT 7 as HOUR, 0)
    UNION (SELECT 8 as HOUR, 0)
    UNION (SELECT 9 as HOUR, 0)
    UNION (SELECT 10 as HOUR, 0)
    UNION (SELECT 11 as HOUR, 0)
    UNION (SELECT 12 as HOUR, 0)
    UNION (SELECT 13 as HOUR, 0)
    UNION (SELECT 14 as HOUR, 0)
    UNION (SELECT 15 as HOUR, 0)
    UNION (SELECT 16 as HOUR, 0)
    UNION (SELECT 17 as HOUR, 0)
    UNION (SELECT 18 as HOUR, 0)
    UNION (SELECT 19 as HOUR, 0)
    UNION (SELECT 20 as HOUR, 0)
    UNION (SELECT 21 as HOUR, 0)
    UNION (SELECT 22 as HOUR, 0)
    UNION (SELECT 23 as HOUR, 0)
)
AS `combined_table`
GROUP BY HOUR
ORDER BY HOUR DESC

Один запрос MySQL по желанию.

3 голосов
/ 13 октября 2010

Это просто часть «почему она не возвращается». Ответ Маркуса охватывает часть «как».

SQL

SELECT 
    hour(TIMESTAMP_X) as HOUR 
    , count(*) AS HOUR_STAT 
FROM cms_webstat 
GROUP BY HOUR 
ORDER BY HOUR DESC 

получает количество записей в час, для отметок времени, представленных в таблице

Он не дает подробностей о том, чего нет в таблице. Поскольку для отметки времени, соответствующей часу 8 (из вашего примера), нет записей, SQL не возвращает никаких записей.

0 голосов
/ 30 мая 2014
$sql = 'SELECT g, MAX(v) AS v, MAX(c) AS c FROM (';
$sql .= '(SELECT DATE_FORMAT(viewed, \'%d.%m.%Y\') AS g, COUNT(1) AS v, 0 AS c FROM '.$this->prefix.'view WHERE campaignid IN ('.join(', ',$ids).') GROUP BY g)';
$sql .= ' UNION (SELECT DATE_FORMAT(clicked, \'%d.%m.%Y\') AS g, 0 AS v, COUNT(1) AS c FROM '.$this->prefix.'clicks WHERE campaignid IN ('.join(', ',$ids).') GROUP BY g)';
$today = strtotime("00:00:00");
for ($i=$today; $i>=time()-30*86400; $i-=86400) {
    $sql .= ' UNION (SELECT \''.date('d.m.Y',$i).'\' AS g, 0 AS v, 0 AS c)';
}
$sql .= ') AS tmp GROUP BY g ORDER BY g DESC';

$chart = DB::getAll($sql);
p($chart);

Спасибо! Сделал это! Из 2-х таблиц, кликов и просмотров, присоединился .. работает. ajaxel.com

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