2013-07-21 49 views
2

我试图让动态列的数据透视表工作。当user_id是一个字符串,它工作正常,但如果它的一个int,那么似乎失败MySQL动态数据透视表

这里是我迄今为止与过去问题的援助:

CREATE TABLE measure2 
    (`inspection_date` date, `user_id` int, `score` int, comment text) 
; 

INSERT INTO measure2 
    (`inspection_date`, `user_id`, `score`, comment) 
VALUES 
    ('2012-10-16', 0, 0, null), 
    ('2012-10-16', 1, 0, null), 
    ('2012-10-16', 2, 0, null), 
    ('2012-10-16', 3, 0, null), 
    ('2012-10-17', 0, 1, null), 
    ('2012-10-17', 1, 1, null), 
    ('2012-10-17', 2, 1, null), 
    ('2012-10-18', 3, 1, null) 
; 


SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when user_id = ''', 
     user_id, 
     ''' then score end) AS ', 
     user_id 
    ) 
) INTO @sql 
FROM measure2; 

SET @sql = CONCAT('SELECT inspection_date, ', @sql, ' 
        FROM measure2 
        GROUP BY inspection_date'); 

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

见:http://sqlfiddle.com/#!2/eab24/1

林肯定它的东西很简单,但我错过了什么?

感谢

回答

2

由于值在int你正在使他们的列名,你必须包装在反引号的值

的SQL的样子:

max(case when user_id = 1 then score end) as `1` 

完整的查询将是:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when user_id = ''', 
     user_id, 
     ''' then score end) AS `', 
     user_id, '`' 
    ) 
) INTO @sql 
FROM measure2; 

SET @sql = CONCAT('SELECT inspection_date, ', @sql, ' 
        FROM measure2 
        GROUP BY inspection_date'); 

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

请参阅SQL Fiddle with Demo

+0

+1 GMTA,正如他们所说... –

+0

非常感谢! –

+0

你好先生,因为我正在挖掘一些动态的数据透视表,这引起了我的注意..我想知道这个查询如何在PHP中工作,或者我怎么能在php – CallMeJeo

1

确实简单 - 单独号码不是有效的SQL列名,因此你需要修改你的代码它们放在反引号:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when user_id = ', 
     user_id, 
     ' then score end) AS `', 
     user_id, 
     '`' 
    ) 
) INTO @sql 
FROM measure2; 

SET @sql = CONCAT('SELECT inspection_date, ', @sql, ' 
        FROM measure2 
        GROUP BY inspection_date'); 

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

我建议保留这一变化为字符串值,以及,以防某些字符串值与保留字匹配或包含空格。

(另外,'不需要围绕数字值,所以我从壳体移除子句它们。)

SQLFiddle here

+0

中做这个查询谢谢!你和bluefeet几乎必须同时发布! –