在 SQL 中将行转换为列
Posted
技术标签:
【中文标题】在 SQL 中将行转换为列【英文标题】:Convert rows to columns in SQL 【发布时间】:2012-12-01 20:09:36 【问题描述】:请问我该怎么做?
【问题讨论】:
您使用的是哪个数据库系统? 发布您正在使用的表结构以及 Yogendra 提出的问题。 你是如何确定你想要C 10 18 0 9
而不是(比如说)C 18 10 9 0
?
我使用 Microsoft SQL Server Express。
亲爱的 ruakh,没有特别的顺序。
【参考方案1】:
您可以使用PIVOT
表运算符将这些课程成绩的行转换为列,如下所示:
SELECT
Course,
[1] AS "Grade 1",
[2] AS "Grade 2",
[3] AS "Grade 3",
[4] AS "Grade 4"
FROM
(
SELECT
Course,
Grade,
ROW_NUMBER() OVER(PARTITION BY Course
ORDER BY COURSE) rownum
FROM Grades
) t
PIVOT
(
MAX(Grade)
FOR rownum IN([1], [2], [3], [4])
) p;
SQL Fiddle Demo
这会给你:
COURSE GRADE 1 GRADE 2 GRADE 3 GRADE 4
A 15 17 (null) (null)
B 12 (null) (null) (null)
C 10 18 0 9
注意:我使用排名函数ROW_NUMBER()
和PARTITION BY Course
将它们划分为四个等级。这样您就可以将它们分成这四组。
如果您需要动态处理,以防有未知数量的成绩。在这种情况下,您可以使用动态 SQL 来动态生成成绩列表,如下所示:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT distinct ','
+ QUOTENAME('Grade '
+ CAST(ROW_NUMBER() OVER(PARTITION BY Course
ORDER BY Course) AS VARCHAR(10)))
FROM Grades
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
SELECT @query = 'SELECT Course, ' + @cols +
'FROM
(
SELECT
Course,
Grade,
''Grade '' + CAST(ROW_NUMBER()
OVER(PARTITION BY Course
ORDER BY COURSE) AS VARCHAR(10)) rownum
FROM Grades
) t
PIVOT
(
MAX(Grade)
FOR rownum IN(' + @cols + ')' +
') p';
execute(@query);
Dynamic SQL Fiddle Demo
【讨论】:
我会用 dense_rank() 改变 row_number,所以如果有双 15 标记,它不会像dense_rank() OVER(PARTITION BY Course ORDER BY Grade) 那样显示在枢轴中以上是关于在 SQL 中将行转换为列的主要内容,如果未能解决你的问题,请参考以下文章