Объединение одинаковых данных из столбцов в одну строку - PullRequest
4 голосов
/ 23 марта 2011

Я пытаюсь объединить частичное содержимое строк, которые являются результирующим набором запроса из SQL Server 2005, который читает .CSV. Вот упрощенная версия данных, которые у меня есть:

objectID  | value1   | value2
_________________________________
12        | R        | 100
12        | R        | 101
12        | S        | 220
13        | D        | 88
14        | K        | 151
14        | K        | 152

То, к чему я пытаюсь добраться, - это группировка значений каждого objectID в одной строке, так что для каждого objectID есть одна и только одна строка. В графическом плане:

objectID  | value1a  | value2a  | value 1b  | value2b  | value1c  | value2c
______________________________________________________________________________
12        | R        | 100      | R         | 101      | S        | 220
13        | D        | 88       |           |          |          |
14        | K        | 151      | K         | 152      |          |

Пустые ячейки пустые.

Я надеялся сделать это в Excel или Access без VB, но CONCAT и другие подобные функции (и ответы здесь и в других местах, предлагающие аналогичные подходы) не работают, потому что каждое значение должно оставаться в своей собственной ячейке (это данные в конечном итоге будут объединены с формой Word). Если ответ является хранимой процедурой или курсором SQL, это нормально, хотя я пока еще не очень эффективен в их написании.

Спасибо всем.

1 Ответ

4 голосов
/ 24 марта 2011

Сначала импортируйте данные во временную таблицу.Временная таблица в итоге будет выглядеть примерно так:

create table #tmp (objectID int, value1 char(1), value2 int)
insert #tmp select
12 ,'R', 100 union all select
12 ,'R', 101 union all select
12 ,'S', 220 union all select
13 ,'D', 88 union all select
14 ,'K', 151 union all select
14 ,'K', 152

Затем вы можете использовать этот пакет SQL, который при необходимости может быть помещен в хранимую процедуру.

declare @sql nvarchar(max)
select @sql = ISNULL(@sql+',','')
        + 'max(case when rn=' + cast(number as varchar) + ' then value1 end) value' + cast(number as varchar) + 'a,'
        + 'max(case when rn=' + cast(number as varchar) + ' then value2 end) value' + cast(number as varchar) + 'b'
from master..spt_values
where type='P' and number between 1 and (
    select top 1 COUNT(*)
    from #tmp
    group by objectID
    order by 1 desc)

set @sql = '
    select objectID, ' + @sql + '
    from (
        select rn=ROW_NUMBER() over (partition by objectID order by value2), *
        from #tmp) p
    group by ObjectID'

exec (@sql)

Выход

objectID    value1a value1b     value2a value2b     value3a value3b
----------- ------- ----------- ------- ----------- ------- -----------
12          R       100         R       101         S       220
13          D       88          NULL    NULL        NULL    NULL
14          K       151         K       152         NULL    NULL
Warning: Null value is eliminated by an aggregate or other SET operation.
...