将 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
比如说我有一个 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