2

我的数据如下所示:

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 的新方法也是值得赞赏的。这将处理大量数据,因此效率很重要。

4

1 回答 1

4

PIVOT您可以使用SQL Server 中的函数转换此数据。为了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

但如果值未知,则需要使用动态 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

两个查询的结果是:

|     ADDRESS | ID_1 | ID_2 | ID_3 | ID_4 |
-------------------------------------------
| 12AnyStreet | 1234 | 1235 | 1236 | 1237 |
于 2013-02-13T16:13:30.727 回答