2012-04-07 51 views
3

考虑下表 “意见”选择行作为MySQL中的列?

user_id _date  cnt 
------------------------ 
1  2011-02-10 123 
1  2011-02-11 99 
1  2011-02-12 100 
1  2011-02 13 12 
2  2011-02-10 32 
2  2011-02-11 433 
2  2011-02-12 222 
2  2011-02 13 334 
3  2011-02-10 766 
3  2011-02-11 654 
3  2011-02-12 43 
3  2011-02 13 27 
... 
100  2011-02-13 235 

正如你可以看到,该表保存每个用户(USER_ID)每天浏览量(CNT)(_DATE)。我在寻找一个SELECT查询,将输出user_ids为列,因此表的数据将是矩阵形式,如下:

_date   1 2 3 ... 100 
--------------------------------- 
2011-02-10 123 32 766 
2011-02-11 99 433 654 
2011-02-12 100 222 43 
2011-02-13 12 334 27  235 

这是可以做到的SELECT语句?

+1

我不认为这是在MySQL中尽可能不包括“转动”命令可能要考虑实施这个逻辑你应用程序层。 – McGarnagle 2012-04-07 23:39:47

+0

您是否正在寻找固定数量的列(对于一组固定的'user_id')或表中的每个'user_id'? – 2012-04-07 23:41:32

+0

固定金额。有一百个user_id。看到OP编辑:-) – Pr0no 2012-04-07 23:52:28

回答

4

如果你正在处理一组有限的用户ID,你可以做这样的事情:

SELECT _date, 
    SUM(CASE WHEN _user_id = 1 THEN cnt ELSE 0 END) AS user1, 
    SUM(CASE WHEN _user_id = 2 THEN cnt ELSE 0 END) AS user2, 
    SUM(CASE WHEN _user_id = 3 THEN cnt ELSE 0 END) AS user3, 
    ... 
FROM views 
GROUP BY _date 

它更像是一个黑客不是一个很好的查询,但。

+1

事实上,如果你正在处理一个大型的数据集,期待缓慢的查询。最好的解决方法,但! – BenOfTheNorth 2012-04-08 00:03:50

+0

谢谢!但是,这个查询给我一个错误:'#1064 - 你的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以获得在''附近使用的正确语法')AS user1,SUM(CASE WHEN user_id = 2 THEN cnt ELSE 0)AS user2,'at line 3'有任何关于为什么发生这种情况的建议? – Pr0no 2012-04-09 12:01:15

+0

@ Pr0no我遗漏了'END';该示例现在已修复。如果你在MySQL文档中查找“CASE”,你可能已经想出了自己的想法。 – benzado 2012-04-09 20:33:13

0

看起来你有一个很长的值列表,你想要转换。如果是这种情况,那么你可以使用prepared statements。您的代码看起来像这样(见SQL Fiddle with Demo):

CREATE TABLE Table1 
    (`user_id` int, `_date` datetime, `cnt` int) 
; 

INSERT INTO Table1 
    (`user_id`, `_date`, `cnt`) 
VALUES 
    (1, '2011-02-09 17:00:00', 123), 
    (1, '2011-02-10 17:00:00', 99), 
    (1, '2011-02-11 17:00:00', 100), 
    (1, '2011-02-13 00:00:00', 12), 
    (2, '2011-02-09 17:00:00', 32), 
    (2, '2011-02-10 17:00:00', 433), 
    (2, '2011-02-11 17:00:00', 222), 
    (2, '2011-02-13 00:00:00', 334), 
    (3, '2011-02-09 17:00:00', 766), 
    (3, '2011-02-10 17:00:00', 654), 
    (3, '2011-02-11 17:00:00', 43), 
    (3, '2011-02-13 00:00:00', 27), 
    (100, '2011-02-12 17:00:00', 235) 
; 

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'sum(case when user_id = ''', 
     user_id, 
     ''' then cnt else 0 end) AS ''', 
     user_id, '''' 
    ) 
) INTO @sql 
FROM Table1; 

SET @sql = CONCAT('SELECT _Date, ', @sql, ' 
        FROM table1 
        GROUP BY _Date'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt;