2011-05-08 39 views
0

考虑这个查询:简单的数据透视查询帮助

SELECT COUNT(*) AS pageviews 
FROM stats_hits 
WHERE pageID='1' AND entrytime>DATE_SUB(now(), INTERVAL 5 DAY) 
GROUP BY DATE(`entrytime`) LIMIT 5 

返回命中计数为过去的五天里:是这样的:

11 
12 
18 
15 
5 

我怎么可以重写此查询返回水平结果集?

11, 12, 18, 15, 5 

谢谢!

编辑:作为一个侧面的问题,没有人知道如何调整此查询显示为0没有命中的日子?此刻如果某一天没有点击,则只返回4个结果。

回答

1
SELECT GROUP_CONCAT(s.pageviews) AS pageviews 
FROM 
    (
    SELECT COUNT(*) AS pageviews 
    FROM stats_hits 
    WHERE pageID='1' AND entrytime>DATE_SUB(now(), INTERVAL 5 DAY) 
    GROUP BY DATE(`entrytime`) LIMIT 5 
) s; 

参见:http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat

如果你想永远有5个结果,这样的事情丑陋的黑客攻击可能会奏效。

SELECT GROUP_CONCAT(s2.pageviews) AS pageviews 
FROM 
    (
    SELECT * FROM 
    (
    SELECT COUNT(*) AS pageviews 
    FROM stats_hits 
    WHERE pageID='1' AND entrytime>DATE_SUB(now(), INTERVAL 5 DAY) 
    GROUP BY DATE(`entrytime`) LIMIT 5 
    UNION ALL SELECT 0 AS pageviews 
    UNION ALL SELECT 0 AS pageviews 
    UNION ALL SELECT 0 AS pageviews 
    UNION ALL SELECT 0 AS pageviews 
    UNION ALL SELECT 0 AS pageviews 
    ) s1 
    ORDER BY pageviews = 0 ASC 
    LIMIT 5) s2; 

另一种选择是这

CREATE TEMPORARY TABLE temp_table LIKE SELECT 0 as pageviews; 
INSERT INTO temp_table VALUES (0),(0),(0),....,(0); 
INSERT INTO temp_table 
    SELECT COUNT(*) AS pageviews 
    FROM stats_hits 
    WHERE pageID='1' AND entrytime>DATE_SUB(now(), INTERVAL x DAY) 
    GROUP BY DATE(`entrytime`) LIMIT x; //replace x with the number of days 

SELECT GROUP_CONCAT(t.pageviews) AS pageviews 
FROM temp_table t 
ORDER BY t.pageview = 0 ASC 
LIMIT x; //replace x with the number of days 
+0

感谢约翰 - 漂亮的快速和肮脏的支点技术。我会记住这一点!我有时不得不查看最近的30或60天,以免上面的黑客无法正常工作。而且它看起来并不像保持结果的顺序,我可能也需要。无论如何,非常感谢帮助。 – cronoklee 2011-05-08 15:53:53

+0

@cronoklee,'group by'按'entrytime'排序结果。中间子查询中的'order by'不会改变这个顺序,不过你可以在内部或外部选择中添加'order by'。 – Johan 2011-05-08 16:01:25

+0

哇看起来很棒 - 谢谢@约翰。我假设在'VALUES(0),(0),(0),...,(0);'我需要添加一个(0)我每天要计数? – cronoklee 2011-05-08 16:21:00