2013-02-13 3 views
2

У меня есть данные, что выглядит следующим образом:SQL Server - Ряды в Колонном без Aggregation

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

Моя цель состоит в том, чтобы сделать его выглядеть следующим образом:

Address id1 id2 id3 id4 
123Any 1234 1235 1246 1237 

Основываясь на некоторых Googling и что нет , я был в состоянии произвести следующее: КТР

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

Следующим шагом будет поворачиваться так, что для каждого РИД, я место т он связал идентификатор в столбце. Тем не менее, я не могу представить пример, который, как мне показалось, работает. Вместо того, чтобы размещать остальную часть примера, которая может даже не применяться, я оставлю ее аудитории. Также приветствуются другие новые подходы, не обязательно использующие CTE. Это будет захватывать множество данных, поэтому эффективность важна.

+0

возможно дубликат [Сплющите переменных строк длины DB в одну колонку] (http://stackoverflow.com/questions/15162348/flatten-variable-length-db-rows -into-a-one-column) – RichardTheKiwi

ответ

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 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 | 
+0

Спасибо. Это работало очень хорошо. Я представил общий случай для моего более конкретного случая, который имеет динамическое количество идентификаторов для каждого домашнего хозяйства. Я знаю минимальные и максимальные суммы, но это зависит от семьи. Я должен быть в состоянии взять это отсюда. Еще раз спасибо! – Jeremy

+0

@ Жереми рады помочь. :) – Taryn

+0

@bluefeet Просто хотел сказать спасибо! Bluefeet вы ответили на множество моих вопросов независимо от того, спросил я их или нет. – Shrout1

Смежные вопросы