MySQL:使用GROUP BY时用空填充空字段

时间:2010-03-19 18:42:20

标签: mysql group-by

我有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 个答案:

答案 0 :(得分:8)

使用单个列创建另一个表

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

答案 1 :(得分:4)

我终于找到了答案。 也许我疯了,但这很有效。

SELECT HOUR, max(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查询。

答案 2 :(得分:3)

这只是'为什么它不归还'的一部分。马库斯的答案涵盖了“如何”的部分。

SQL

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

获取每小时记录的计数,获取表中的时间戳

它没有详细说明表中没有的内容。由于时间戳没有与小时8对应的时间戳(来自您的示例),因此SQL不会返回任何记录。

答案 3 :(得分:0)

$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