2010-05-13 3 views
3

У нас есть немного quandry SQL. Скажите, у меня есть результаты, которые выглядят так ...SQL 2005 Объединить/объединить несколько строк в один столбец

61E77D90-D53D-4E2E-A09E-9D6F012EB59C | A
61E77D90-D53D-4E2E-A09E-9D6F012EB59C | B
61E77D90-D53D-4E2E-A09E-9D6F012EB59C | C
61E77D90-D53D-4E2E-A09E-9D6F012EB59C | D
7ce953ca-a55b-4c55-a52c-9d6f012ea903 | E
7ce953ca-a55b-4c55-a52c-9d6f012ea903 | F

есть способ, которым я могу сгруппировать эти результаты в рамках SQL для возвращения

61E77D90-D53D-4E2E-A09E-9D6F012EB59C | A B C D
7ce953ca-a55b-4c55-a52c-9d6f012ea903 | E F

Любые идеи людей?

Большое спасибо

Dave

+0

Вы должны быть в состоянии сделать это путем объединения STUFF() с ROW_COUNT(). Я не эксперт по TSQL, хотя ... –

ответ

1

Я предпочитаю, чтобы определить пользовательский определенный пользователем агрегат. Here's an example UDA, который выполнит что-то очень близкое к тому, что вы просите.

Зачем использовать определяемую пользователем совокупность вместо вложенного SELECT? Это все о производительности и о том, что вы готовы мириться. Для небольшого количества элементов вы можете наверняка уйти с вложенным SELECT, но для большого «n» вы заметите, что в плане запроса по существу выполняется вложенный SELECT один раз для каждой строки в выходном списке. Это может быть поцелуй смерти, если вы говорите о большом количестве рядов. С UDA можно объединить эти значения за один проход.

Компромисс, конечно же, заключается в том, что UDA требует от вас использовать CLR для его развертывания, и это часто не так много людей. В Oracle, эта конкретная ситуация немного лучше, как вы можете использовать PL/SQL directly создать определенный пользователем агрегат, но я отвлекся ...

+0

Спасибо, это была лучшая реализация для нас. – Dave

+0

Я не знаю, почему это было пропущено; Я проголосовал за это, потому что кажется, что это законное (и, возможно, элегантное) решение, которое также отвечает на исходный вопрос[email protected] - было бы полезно (для других, которые находят этот вопрос и его ответы), чтобы знать * почему * это был лучший ответ для вас. –

+0

Спасибо. Я изложил свой ответ. Посмотрите, теперь вы уменьшите его ;-) –

5

попробовать это:

set nocount on; 
declare @t table (id char(36), x char(1)) 
insert into @t (id, x) 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'A' union 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'B' union 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'C' union 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'D' union 
select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'E' union 
select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'F' 
set nocount off 

SELECT p1.id, 
      stuff(
        (SELECT 
         ' ' + x 
         FROM @t p2 
         WHERE p2.id=p1.id 
         ORDER BY id, x 
         FOR XML PATH('') 
        ) 
        ,1,1, '' 
       ) AS YourValues 
     FROM @t p1 
     GROUP BY id 

ВЫВОД:

id         YourValues 
------------------------------------ -------------- 
61E77D90-D53D-4E2E-A09E-9D6F012EB59C A B C D 
7ce953ca-a55b-4c55-a52c-9d6f012ea903 E F 

(2 row(s) affected) 

EDIT
на основе комментарий OP в об этом необходимости выполнения существующего запроса, попробуйте следующее:

;WITH YourBugQuery AS 
(
    --replace this with your own query 
    select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' AS ColID , 'A' AS ColX 
    union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'B' 
    union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'C' 
    union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'D' 
    union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'E' 
    union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'F' 

) 
SELECT p1.ColID, 
      stuff(
        (SELECT 
         ' ' + ColX 
         FROM YourBugQuery p2 
         WHERE p2.ColID=p1.ColID 
         ORDER BY ColID, ColX 
         FOR XML PATH('') 
        ) 
        ,1,1, '' 
       ) AS YourValues 
     FROM YourBugQuery p1 
     GROUP BY ColID 

это тот же набор результатов, что и выше.

+1

+1 Очень приятно! '' –

+0

Спасибо - но я должен, вероятно, указать, что результаты получены из SQL-запроса, поэтому я не могу предсказать, какими будут результаты для того, чтобы я объединил их подряд за строкой. – Dave

+0

@Dave, в моем примере кода я использую все UNION, чтобы просто заполнить таблицу @t, они не имеют никакого отношения к решению, просто способ получить данные в таблицу для запроса. Я отредактирую вопрос на использование CTE, чтобы вы могли заставить его работать над любым запросом (первый пример кода работал в таблице). –

0

Другой способ сделать это состоит в использовании для опции PATH XML

SELECT 
    [ID], 
    (
     SELECT 
      [Value] + ' ' 
     FROM 
      [YourTable] [YourTable2] 
     WHERE 
      [YourTable2].[ID] = [YourTable].[ID] 
     ORDER BY 
      [Value] 
     FOR XML PATH('') 
    ) [Values] 
FROM 
    [YourTable] 
GROUP BY 
    [YourTable].[ID]