2014-01-17 3 views
4

Я пытаюсь объединить несколько строк из одной таблицы с общим идентификатором. Таким образом, в образце ниже GroupIdentifier из 1111111111111 становится 1 записей с каждой из записей, включенных в качестве sub Field_#. Некоторые записи могут содержать 3 результатов, которые объединяются в 1, но некоторые могут иметь только 1 или 2.Создать 1 запись из нескольких строк

Благодаря

Примеры данных

GroupIdentifier UniqueIdentifier Direction UserID 

1111111111111 123456789  1   98685 
1111111111111 123456790  2   4469 
1111111111111 123456856  1   98685 
1111115555555 123458765  2   5435 
2222225353535 123454321  1   6565 
2222225353535 123458765  3   4444 

Ожидаемый результат:

GroupIdentifier UniqueID_1 UniqueDirection_1 UserID_1 UniqueID_2 UniqueDirection_2 UserID_2 UniqueID_3 UniqueDirection_3 UserID_3 
1111111111111 123456789 1     98685  123456790 2     4469  123456856 1     98685 
1111115555555 123458765 2     5435 
2222225353535 123454321 1     6565  123458765 3     4444 
+0

Есть ли фиксированное количество строк, которые могут возникнуть? Так это всегда 1 - 2 - 3 или это гибкое? –

+3

Почти всегда легче сделать этот тип * pivot * (который, возможно, является термином, который вы ищете для получения более значимых результатов поиска) в том, что * потребляет * этот набор результатов (т.е. другой язык, который более ориентирован на форматирование и внешний вид, а не данные) –

+1

Общий термин, данный для этого способа обработки данных, - PIVOT. Прочитайте: http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx - и добро пожаловать в раздражающий мир PIVOTing ... – MarkD

ответ

3

Это «многоколоночный шарнир». Самый простой способ - сделать это вручную с помощью GROUP BY и MIN (CASE ..), но он также является наименее гибким, если ваш проект изменится.

WITH t AS (SELECT *, ROW_NUMBER() OVER(PARTITION BY GroupIdentifier ORDER BY DateTime) AS SortOrder FROM MyTable) 
SELECT 
    GroupIdentifier, 
    MIN(CASE SortOrder WHEN 1 THEN UniqueIdentifier END) UniqueIdentifier_1, 
    MIN(CASE SortOrder WHEN 1 THEN Direction  END) Direction_1, 
    MIN(CASE SortOrder WHEN 1 THEN UserID   END) UserID_1, 
    MIN(CASE SortOrder WHEN 2 THEN UniqueIdentifier END) UniqueIdentifier_2, 
    MIN(CASE SortOrder WHEN 2 THEN Direction  END) Direction_2, 
    MIN(CASE SortOrder WHEN 2 THEN UserID   END) UserID_2, 
    MIN(CASE SortOrder WHEN 3 THEN UniqueIdentifier END) UniqueIdentifier_3, 
    MIN(CASE SortOrder WHEN 3 THEN Direction  END) Direction_3, 
    MIN(CASE SortOrder WHEN 3 THEN UserID   END) UserID_3 
) FROM t 
GROUP BY GroupIdentifier 
+0

Вы сейчас мой самый лучший друг, он работал как чемпион! – TalkingScientist

+0

Не знаю, что вы подразумеваете под «наименее гибким», но с точки зрения синтаксиса я бы предпочел этот метод, например, для нескольких соединений. –

+0

@AndriyM, по «негибким», я имею в виду, что тривиальные изменения дизайна несут многократные изменения кода. – Anon

0

Вы могли бы использовать что-то вроде этого. При этом порядок составляет 1, 2, 3 и т. Д.

with x 
as 
(select GroupIdentifier 
    ,  UniqueIdentifier 
    ,  Direction 
    ,  rank() over (partition by GroupIdentifier order by Direction) index 
    from TABLE_NAME 
) 
select one.GroupIdentifier 
,  one.UniqueIdentifier UniqueID_1 
,  one.Direction UniqueDirection_1 
,  one.UserID UserID_1 
,  two.UniqueIdentifier UniqueID_2 
,  two.Direction UniqueDirection_2 
,  two.UserID UserID_2 
,  three.UniqueIdentifier UniqueID_3 
,  three.Direction UniqueDirection_3 
,  three.UserID UserID_3 
from x one 
left 
outer 
join x two 
on  one.GroupIdentifier = two.GroupIdentifier 
and two.index = 2 
left 
outer 
join x three 
on  one.GroupIdentifier = three.GroupIdentifier 
and three.index = 3 
where one.index = 1 
+0

Я пытался сделать что-то подобное, но не мог заставить его работать. Направления не обязательно в порядке, иногда может быть 1 иногда 1, 2,1 иногда 2, 1, 1. Это безумие. – TalkingScientist

+0

см. Обновленный ответ. –

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