【问题标题】:SQL Server - Rows to Columns without AggregationSQL Server - 没有聚合的行到列
【发布时间】:2013-01-29 05:54:27
【问题描述】:

我的数据如下所示:

address      | id  
12AnyStreet  | 1234  
12AnyStreet  | 1235  
12AnyStreet  | 1236  
12AnyStreet  | 1237 

我的目标是让它看起来像这样:

Address  id1   id2   id3   id4   
123Any   1234  1235  1246  1237

基于一些谷歌搜索,我能够生成以下 CTE:

with cust_cte (Address, id, RID) as (
    SELECT Address, id, 
           ROW_NUMBER() OVER (PARTITION BY (Address) ORDER BY Address) AS RID 
    FROM tab)  

下一步是旋转,以便对于每个 RID,我将关联的 id 放在列中。但是,我似乎无法找到我发现的示例。我不会发布甚至可能并不真正适用的示例的其余部分,而是将其留给观众。其他不一定使用 CTE 的新方法也是值得赞赏的。这将处理大量数据,因此效率很重要。

【问题讨论】:

标签: sql sql-server tsql pivot


【解决方案1】:

您可以使用 SQL Server 中的 PIVOT 函数转换此数据。为了PIVOT 数据,您需要使用row_number() 创建新列。

如果您有已知数量的值,则可以对查询进行硬编码:

select *
from
(
  select address, id,
    'id_'+cast(row_number() over(partition by address 
                                order by id) as varchar(20)) rn
  from yourtable
) src
pivot
(
  max(id)
  for rn in ([id_1], [id_2], [id_3], [id_4])
) piv

SQL Fiddle with Demo

但如果值未知,则需要使用动态 SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' 
                      + QUOTENAME(rn) 
                    from
                    (
                      select 'id_'+cast(row_number() over(partition by address 
                                order by id) as varchar(20)) rn
                      from yourtable
                    ) src
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT address,' + @cols + ' from 
             (
                select address, id,
                  ''id_''+cast(row_number() over(partition by address 
                                              order by id) as varchar(20)) rn
                from yourtable
            ) x
            pivot 
            (
                max(id)
                for rn in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demo

两个查询的结果是:

|     ADDRESS | ID_1 | ID_2 | ID_3 | ID_4 |
-------------------------------------------
| 12AnyStreet | 1234 | 1235 | 1236 | 1237 |

【讨论】:

  • 谢谢。这工作得很好。我为我的更具体的案例提供了一个一般案例,每个家庭确实有一个动态的 id 数量。我知道最小和最大 id 数量,但它因家庭而异。我应该可以从这里拿走它。再次感谢!
  • @bluefeet 只是想说声谢谢! Bluefeet 你已经回答了我无数的问题,无论我是不是问他们的人。
  • @Shrout1 欢迎您,我很高兴您从我的回答中得到了一些好处。 :)
  • @bluefeet 这真是一个绝妙的解决方案!
猜你喜欢
  • 2013-03-24
  • 2019-07-03
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多