我有一张包含研究生ID,学位和毕业年份的表格。该表可以包含每个毕业生的任意数量的行。
我想创建一个视图,将所有行转换为所需数量的列,并在没有数据的列中输入“null”。
我在这里已经看过很多次这个问题,但我担心他们要么没有被标记为已回答,要么我不理解解决方案。所以我再次提出这个问题,希望使用我的表结构,我会更好地理解解决方案。
非常感谢任何帮助。
修改 这不一定是视图
答案 0 :(得分:2)
在answer中详细描述了执行此操作的一般方法,但是当您希望按特定顺序(degree1,year1,degree2,year2,等...)可能有点棘手。
这是一种方法,我相信如果您查看我上面链接的答案,代码是不言自明的,我将不再进一步解释:
DECLARE @sql AS NVARCHAR(MAX)
DECLARE @title_cols AS NVARCHAR(MAX)
DECLARE @year_cols AS NVARCHAR(MAX)
DECLARE @header AS NVARCHAR(MAX)
SELECT
@title_cols = ISNULL(@title_cols + ',','') + QUOTENAME(rn),
@year_cols = ISNULL(@year_cols + ',','') + QUOTENAME(CONCAT('y',rn)),
@header = ISNULL(@header + ',','') + CONCAT('MAX(',QUOTENAME(rn) ,') AS "Degree Title ', rn, '", MAX(',QUOTENAME(CONCAT('y',rn)) ,') AS "Graduation Year ', rn, '"')
FROM (
SELECT DISTINCT
rn = ROW_NUMBER() OVER (PARTITION BY [Graduate ID] ORDER BY [Degree Title], [Graduation Year])
FROM Graduates
) GRADS
SET @sql =
N'SELECT [Graduate ID], ' + @header + '
FROM (
SELECT *,
title = ROW_NUMBER() OVER (PARTITION BY [Graduate ID] ORDER BY [Graduation Year]),
year = CONCAT(''y'',ROW_NUMBER() OVER (PARTITION BY [Graduate ID] ORDER BY [Graduation Year]))
FROM Graduates) g
PIVOT(MAX([Degree Title]) FOR title IN (' + @title_cols + ')) AS Titles
PIVOT(MAX([Graduation Year]) FOR year IN (' + @year_cols + ')) AS Years
GROUP BY [Graduate ID]'
EXEC sp_executesql @sql
该查询使用SQL Server 2012及更高版本中提供的concat()
函数,因此如果您使用的是旧版本,则必须将该部分更改为使用强制转换的“正常”字符串连接。
我确信可以通过多种方式改进查询,但我会将其作为练习:)