2012-07-03 2 views
1

У меня есть таблица данных:Как объединить строки данных в T-SQL

|Key|Field |DateField | 
|A |Value1|2012-06-01| 
|A |Value2|2012-06-02| 
|A |Value3|2012-06-03| 
|B |Value4|2012-06-04| 
|B |Value5|2012-06-05| 

Я хочу, чтобы объединить эту строку данных по ключевым - как в группе, но я не могу работать, как. То, что я хочу, чтобы в конечном итоге это:

|Key|Field Aggregate  | 
|A |Value1, Value2, Value3| 
|B |Value4, Value5  | 

еще лучше было бы, чтобы в конечном итоге с позиции последовательности, вставленной в агрегацию, где порядок последовательности определяется порядком соответствующего поля даты.

|Key|Field Aggregate    | 
|A |1: Value1, 2: Value2, 3: Value3| 
|B |1: Value4, 2: Value5   | 

Это похоже на то, я мог бы сделать с общей таблицы выражения, но я, кажется, не быть в состоянии работать как.

Я бы обычно не выполнял такую ​​операцию в SQL - я бы обычно извлекал данные в приложение и манипулировал им по мере необходимости в коде.

К сожалению, это не похоже на вариант в этом случае.

Как это сделать в SQL Server 2005 T-SQL.

Является ли CTE правильным подходом? Есть ли что-то более подходящее?

+0

Как вы определяете последовательность? Является ли это алфавитом в поле «Поле», или есть другой столбец, который мы не можем видеть, который диктует порядок? –

+0

Хороший вопрос, обновили вопрос, чтобы уточнить. –

ответ

4
DECLARE @t TABLE([Key] CHAR(1), [Field] VARCHAR(32), DateField DATETIME); 

INSERT @t SELECT 'A','Value1','20120601' 
UNION ALL SELECT 'A','Value2','20120602' 
UNION ALL SELECT 'A','Value3','20120603' 
UNION ALL SELECT 'B','Value4','20120604' 
UNION ALL SELECT 'B','Value5','20120605'; 

;WITH x AS 
(
    SELECT [Key], [Field], rn = ROW_NUMBER() OVER 
    (PARTITION BY [Key] ORDER BY [DateField]) 
    FROM @t 
) 
SELECT [Key], [Field Aggregate] = STUFF(
    (SELECT ', ' + CONVERT(VARCHAR(12), rn) + ': ' + [Field] 
    FROM x AS x2 WHERE x2.[Key] = x.[Key] 
    ORDER BY rn 
    FOR XML PATH('') 
), 1, 2, '') 
FROM x 
GROUP BY [Key] 
ORDER BY [Key]; 

Результаты:

Key Field Aggregate 
--- ------------------------------- 
A 1: Value1, 2: Value2, 3: Value3 
B 1: Value4, 2: Value5 

P.S. если значения в Field могут содержать символы, которые являются проблематичными для XML (например &, >, < и т.д.) вы хотите изменить эту строку:

), 1, 2, '') 

Для этого:

, TYPE).value('.', 'nvarchar(max)'), 1, 2, '') 

(Это предотвратит предоставление разрешения.)

+0

Порядок определяется дополнительным полем DateTime в исходной таблице. Извините - я добавил, что бит в вопрос в качестве запоздалой мысли и не проверял вопрос по-прежнему имеет смысл. –

+0

Я обновил для заказа 'DateField', хотя в ваших образцовых данных он ничего не меняет ... –

+0

Этот тип кода - это то, почему я ненавижу и люблю SQL Server. – bfavaretto

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