SQL 将行转置为未定义的列数

SQL Transpose Rows to undefined number of columns

我有一个 table,其中包含毕业生 ID、学位名称和毕业年份。 table 可以包含每个毕业生的任意行数。

我想创建一个视图,根据需要将所有行转换为尽可能多的列,并在没有数据的列中输入 'null'。

我已经看到这个问题在这里被问过好几次了,但恐怕他们要么没有被标记为已回答,要么我不明白解决方案。所以我再次问了这个问题,希望使用我的 table 结构我能更好地理解解决方案。

非常感谢您一如既往的帮助。

编辑: 这不一定是视图

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

Sample SQL Fiddle

该查询使用 concat() 函数,该函数在 SQL Server 2012 及更高版本中可用,因此如果您使用的是旧版本,则必须将该部分更改为 "normal" 带转换的字符串连接。

我确信查询可以在很多方面得到改进,但我会把它留作练习 :)

以ug为 (select * 来自学位名称如“B%”的毕业生) 以 pg 作为 (select * 来自学位名称如“M%”的毕业生) 以 pg1 作为 (select * 来自学位名称如“P%”的毕业生)

select ug.id 作为毕业生 ID , ug.Degree Title as Degree Title 1 ,呃。毕业年作为毕业年 1 , pg1.Degree Title as Degree Title 2 , 第 1 页。毕业年作为毕业年 2 , pg2.Degree Title as Degree Title 3 , 第 2 页。毕业年作为毕业年 3 来自 ug 左加入 pg1 关于 ug.Graduate ID= pg1.Graduate ID 左加入pg2 关于 ug.Graduate ID= pg2.Graduate ID