将 ID 相同但属性不同的记录合并为一条记录

Combine records with same ID, but different attributes into one record

比如说我有一个 table 有以下记录...

ID | Attribute
1      BLUE
1      GREEN
1      RED
2      YELLOW
2      GREEN
3      GREEN

我想把它压缩成1条记录所有的属性。

ID | Attribute1 | Attribute2 | Attribute3
1      BLUE         GREEN         RED
2      YELLOW       GREEN
3      GREEN

我正朝着 PIVOT 的方向前进,但不知道如何将属性明确地插入到单独的列中,因为它们共享相同的 ID/Key。我正在使用 SSMS。

如果您不需要动态,条件聚合可能会有所帮助

Select ID
      ,max(case when RN=1 then Attribute else '' end)) as Attribute1 
      ,max(case when RN=2 then Attribute else '' end)) as Attribute2 
      ,max(case when RN=3 then Attribute else '' end)) as Attribute3
 From (
        Select *
              ,RN = Row_Number() over (Partition By ID Order By Attribute)
         From YourTable
      )
 Group By ID

试试这个

;WITH cte
     AS (SELECT *,Row_number()OVER(partition BY [ID] ORDER BY [Attribute]) rn
         FROM   Yourtable)
SELECT [ID],
       Max(CASE WHEN rn = 1 THEN [Attribute] ELSE '' END) AS [Attribute1],
       Max(CASE WHEN rn = 2 THEN [Attribute] ELSE '' END) AS [Attribute2],
       Max(CASE WHEN rn = 3 THEN [Attribute] ELSE '' END) AS [Attribute3]
FROM   cte
GROUP  BY [ID] 

如果您想使用未知数量的属性,那么

DECLARE @int INT = 1,
        @cnt INT,
        @sql VARCHAR(max)

SELECT TOP 1 @cnt = Count(1)OVER(partition BY [ID])
FROM   Yourtable
ORDER  BY Count(1)OVER(partition BY [ID]) DESC

SET @sql = ';WITH cte
         AS (SELECT *,Row_number()OVER(partition BY [ID] ORDER BY [Attribute]) rn
             FROM   Yourtable)
    SELECT [ID],'

WHILE @int <= @cnt
  BEGIN
      SET @sql += 'Max(CASE WHEN rn = ' + Cast(@int AS VARCHAR(20)) + ' THEN [Attribute] ELSE '''' END) AS [Attribute' + Cast(@int AS VARCHAR(20)) + '],'
      SET @int +=1
  END

SET @sql = LEFT(@sql, Len(@sql) - 1)
SET @sql += 'FROM   cte GROUP  BY [ID]' 

exec (@sql)

这应该有效并且使用起来非常简单

select * from(
        select 
             ID
            ,Attribute
            ,row_number() over(partition by ID order by Attribute) as AttributeNumber
        from [YourTable]
        group by ID
                ,Attribute
            )t1
PIVOT
(
MAX(Attribute)
FOR AttributeNumber in ([1],[2],[3])-- add more as needed
)piv