【问题标题】:Combine records with same ID, but different attributes into one record将具有相同ID但不同属性的记录合并为一条记录
【发布时间】:2017-05-05 23:53:27
【问题描述】:

例如,我有一个包含以下记录的表...

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

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

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

我正在走 PIVOT 的道路,但考虑到它们共享相同的 ID/Key,我不知道如何将属性明确插入到单独的列中。我正在使用 SSMS。

【问题讨论】:

  • 您使用的是哪个DBMS
  • 每个ID最多可以有3个Attributes或者未知?
  • SQL Server 管理工作室
  • 对于我目前正在处理的表,我拥有的最大属性是 3 个。

标签: sql sql-server tsql pivot


【解决方案1】:

试试这个

;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)

【讨论】:

  • 这很完美!我只是输入了 NULL 而不是 ' '。感谢帮助!在使用 CTE 时需要提高一点。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    这应该可以工作并且使用起来非常简单

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 2014-02-10
      • 2015-07-02
      相关资源
      最近更新 更多