我有这张桌子:
idSection | idQuestion | title | enunciation | total | name
1 | 1 | title 1 | question 1 | 5 | Good
1 | 1 | title 1 | question 1 | 3 | Very Good
1 | 1 | title 1 | question 1 | 1 | Bad
1 | 2 | title 2 | question 2 | 1 | Good
1 | 2 | title 2 | question 2 | 3 | Bad
1 | 3 | title 3 | question 3 | 1 | Bad
如何在多列中创建列值名称。
以下是预期结果:
title | enunciantion | bad | good | very good
title 1 | question 1 | 1 | 5 | 3
title 2 | question 2 | 3 | 1 | 0
title 3 | question 3 | 1 | 0 | 0
我不知道会有多少列(它是动态的)。
新编辑:
title | enunciantion | Column0 | Column1 | Column2 | ... | Column7 |
0 | 0 | bad | good |very good| ... | 0 |
title 1 | question 1 | 1 | 5 | 3 | ... | 0 |
title 2 | question 2 | 3 | 1 | 0 | ... | 0 |
title 3 | question 3 | 1 | 0 | 0 | ... | 5 |
现在,唯一的区别是,不是拥有动态列,而是只有静态列,但是表的第一行是这样的动态值,范围是另一个表。
答案 0 :(得分:3)
对于MySQL:
SELECT
title,
enunciantion,
SUM(CASE WHEN name = 'bad' THEN total ELSE 0 END) AS 'bad',
SUM(CASE WHEN name = 'good' THEN total ELSE 0 END) AS 'good',
SUM(CASE WHEN name = 'very good ' THEN total ELSE 0 END) AS 'very good'
FROM Tablename
GROUP BY title,
enunciantion;
对于SQL Server:
SELECT
title,
enunciation,
bad,
good,
[very good]
FROM Table1
PIVOT
(
SUM(total) FOR name IN([good], [bad], [very good])
) p;
如果这些值good, bad, very good
来自另一个表,并且您想要动态执行此操作。
对于MySQL:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT('SUM(IF(Name = ''',
Name, ''', Total, 0)) AS ',
'''',Name, '''')
) INTO @sql
FROM names;
SET @sql = CONCAT('SELECT title, enunciation, ',
@sql,
'FROM Table1 GROUP BY title, '
' enunciation; ');
prepare stmt
FROM @sql;
execute stmt;
| TITLE | ENUNCIATION | GOOD | VERY GOOD | BAD | VERY BAD |
-------------------------------------------------------------
| title 1 | question 1 | 5 | 3 | 1 | 0 |
| title 2 | question 2 | 1 | 0 | 3 | 0 |
| title 3 | question 3 | 0 | 0 | 1 | 0 |
对于SQL Server,您可以这样做:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.name)
from names c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = 'SELECT title, enunciation, ' + @cols +
' FROM (SELECT title, enunciation, total, name
FROM Table1) t
PIVOT
(
SUM(total) FOR name IN( ' + @cols + + ' )) p;';
execute(@query);
这会给你:
| TITLE | ENUNCIATION | BAD | GOOD | VERY BAD | VERY GOOD |
---------------------------------------------------------------
| title 1 | question 1 | 1 | 5 | (null) | 3 |
| title 2 | question 2 | 3 | 1 | (null) | (null) |
| title 3 | question 3 | 1 | (null) | (null) | (null) |
答案 1 :(得分:3)
仅针对SQL Server的动态SQL版本扩展@Mahmoud Gamal's答案。如果要将null
值替换为零,则可以使用以下内容:
DECLARE @colsPivot AS NVARCHAR(MAX),
@colsNull AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(c.name)
from names c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsNull
= STUFF((SELECT distinct ', IsNull(' + QUOTENAME(c.name) + ', 0) as '+ QUOTENAME(c.name)
from names c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = 'SELECT title, enunciation, ' + @colsNull +
' FROM
(
SELECT title, enunciation, total, name
FROM results
) t
PIVOT
(
SUM(total)
FOR name IN( ' + @colsPivot + + ' )
) p;';
exec(@query);
结果是:
| TITLE | ENUNCIATION | BAD | GOOD | VERY BAD | VERY GOOD |
-------------------------------------------------------------
| title 1 | question 1 | 1 | 5 | 0 | 3 |
| title 2 | question 2 | 3 | 1 | 0 | 0 |
| title 3 | question 3 | 1 | 0 | 0 | 0 |