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

标签 sql sql-server pivot transpose

我有一个包含毕业生 ID、学位名称和毕业年份的表格。该表可以包含每个毕业生的任意数量的行。

Current Table structure

我想创建一个 View ,将所有行转置为所需数量的列,并在没有数据的列中输入“null”。

Desired output

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

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

编辑: 这不一定是 View

最佳答案

answer 中详细描述了执行此操作的通用方法。 ,但是当您希望列按特定顺序(学位 1、年份 1、学位 2、年份 2 等...)时,以动态方式将其应用于多个列可能会有点棘手。

这是实现此目的的一种方法,因为我相信如果您已经查看了我上面链接的答案,则代码是非常不言自明的,我不会进一步解释它:

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

查询使用 SQL Server 2012 及更高版本中提供的 concat() 函数,因此如果您使用的是旧版本,则必须将该部分更改为“正常”字符串连接与类型转换。

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

关于SQL 将行转置为未定义数量的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30321217/

相关文章:

sql - 使 SQL Server 成为链接服务器

sql-server - Azure SQL 数据库中的异步触发器

SQL 检查用户关系是否存在

php - 更新本地存储中的时间

sql - sql server 2012 小数点后只删除零

python - 使用另一个 DataFrame 创建或修改 DataFrame

linq - 使用 LINQ 的动态枢轴是否可能?

MySQL相关 'projects'查询

c# - 多个左连接的 LINQ 方法语法

R 如何旋转具有不同长度类别的表(具有两列)?