2014-01-21 5 views
7

Я видел много вопросов о PIVOT для одного столбца, каждый вопрос более сложный, чем другие, однако я не мог найти ничего похожего на то, что мне нужно.SQL Server - PIVOT - два столбца в строках

Если честно, я даже не знаю, поможет ли мне в этой ситуации ось опоры.

Скажем, у меня есть эти данные на моей исходной таблицы:

SELECT '1' as 'RowId', 'RandomName1' as 'First', 'RandomLast1' as 'Last' 
UNION 
SELECT '2' as 'RowId', 'RandomName2' as 'First', 'RandomLast2' as 'Last' 
UNION 
SELECT '3' as 'RowId', 'RandomName3' as 'First', 'RandomLast3' as 'Last' 
UNION 
SELECT '4' as 'RowId', 'RandomName4' as 'First', 'RandomLast4' as 'Last' 
UNION 
SELECT '5' as 'RowId', 'RandomName5' as 'First', 'RandomLast5' as 'Last' 

максимум 5 строк с именем и фамилией. Значение столбцов First и Last будет случайным.

RowId First  Last 
----- ----------- ----------- 
1  RandomName1 RandomLast1 
2  RandomName2 RandomLast2 
3  RandomName3 RandomLast3 
4  RandomName4 RandomLast4 
5  RandomName5 RandomLast5 

Я пытался повернуть эти данные что-то вроде этого:

First1  Last1  First2  Last2  First3  Last3  First4  Last4  First5  Last5 
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- 
RandomName1 RandomLast1 RandomName2 RandomLast2 RandomName3 RandomLast3 RandomName4 RandomLast4 RandomName5 RandomLast5 

Например: у меня нет никакой проблемы, если столбцы First5 и Last5 являются NULL, потому что есть только 4 строки ,

First1  Last1  First2  Last2  First3  Last3  First4  Last4  First5  Last5 
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- 
RandomName1 RandomLast1 RandomName2 RandomLast2 RandomName3 RandomLast3 RandomName4 RandomLast4 NULL  NULL 

Может ли кто-нибудь мне немного помочь? Спасибо.


Решение основано на Шила K R отвечает:

SELECT 
    MAX(First1) as 'First1', MAX(Last1) as 'Last1', 
    MAX(First2) as 'First2', MAX(Last2) as 'Last2', 
    MAX(First3) as 'First3', MAX(Last3) as 'Last3', 
    MAX(First4) as 'First4', MAX(Last4) as 'Last4', 
    MAX(First5) as 'First5', MAX(Last5) as 'Last5' 
FROM 
(
    SELECT 
     CASE WHEN RowId = 1 THEN [First] END as 'First1', 
     CASE WHEN RowId = 1 THEN [Last] END as 'Last1', 
     CASE WHEN RowId = 2 THEN [First] END as 'First2', 
     CASE WHEN RowId = 2 THEN [Last] END as 'Last2', 
     CASE WHEN RowId = 3 THEN [First] END as 'First3', 
     CASE WHEN RowId = 3 THEN [Last] END as 'Last3', 
     CASE WHEN RowId = 4 THEN [First] END as 'First4', 
     CASE WHEN RowId = 4 THEN [Last] END as 'Last4', 
     CASE WHEN RowId = 5 THEN [First] END as 'First5', 
     CASE WHEN RowId = 5 THEN [Last] END as 'Last5' 
    FROM 
    (
     SELECT '1' as 'RowId', 'RandomName1' as 'First', 'RandomLast1' as 'Last' 
     UNION SELECT '2' as 'RowId', 'RandomName2' as 'First', 'RandomLast2' as 'Last' 
     UNION SELECT '3' as 'RowId', 'RandomName3' as 'First', 'RandomLast3' as 'Last' 
     UNION SELECT '4' as 'RowId', 'RandomName4' as 'First', 'RandomLast4' as 'Last' 
     --UNION SELECT '5' as 'RowId', 'RandomName5' as 'First', 'RandomLast5' as 'Last' 
    ) test 
) test2 

ответ

9

Есть несколько способов, которые вы можете получить результат, который вы хотите. Подобный @Sheela K R's ответ вы можете использовать агрегатную функцию с выражением CASE, но она может быть записана в более краткой форме:

select 
    max(case when rowid = 1 then first end) First1, 
    max(case when rowid = 1 then last end) Last1, 
    max(case when rowid = 2 then first end) First2, 
    max(case when rowid = 2 then last end) Last2, 
    max(case when rowid = 3 then first end) First3, 
    max(case when rowid = 3 then last end) Last3, 
    max(case when rowid = 4 then first end) First4, 
    max(case when rowid = 4 then last end) Last4, 
    max(case when rowid = 5 then first end) First5, 
    max(case when rowid = 5 then last end) Last5 
from yourtable; 

См SQL Fiddle with Demo.

Это также может быть написано с использованием функции PIVOT, однако, поскольку вы хотите развернуть несколько столбцов, вам сначала нужно взглянуть на разворачивание столбцов First и Last.

Процесс, связанный с невиновными, преобразует ваши несколько столбцов в несколько строк данных. Вы не указали, какую версию SQL Server вы используете, но вы можете использовать SELECT с UNION ALL с CROSS APPLY или даже функциями UNPIVOT для выполнения первого преобразования:

select col = col + cast(rowid as varchar(10)), value 
from yourtable 
cross apply 
(
    select 'First', First union all 
    select 'Last', Last 
) c (col, value) 

См SQL Fiddle with Demo.Это преобразует данные в формат:

| COL |  VALUE | 
|--------|-------------| 
| First1 | RandomName1 | 
| Last1 | RandomLast1 | 
| First2 | RandomName2 | 
| Last2 | RandomLast2 | 

После того, как данные в несколько строк, то вы можете легко применить функцию PIVOT:

select First1, Last1, 
    First2, Last2, 
    First3, Last3, 
    First4, Last4, 
    First5, Last5 
from 
(
    select col = col + cast(rowid as varchar(10)), value 
    from yourtable 
    cross apply 
    (
    select 'First', First union all 
    select 'Last', Last 
) c (col, value) 
) d 
pivot 
(
    max(value) 
    for col in (First1, Last1, First2, Last2, 
       First3, Last3, First4, Last4, First5, Last5) 
) piv; 

См SQL Fiddle with Demo

Оба дают результат :

|  FIRST1 |  LAST1 |  FIRST2 |  LAST2 |  FIRST3 |  LAST3 |  FIRST4 |  LAST4 |  FIRST5 |  LAST5 | 
|-------------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|-------------| 
| RandomName1 | RandomLast1 | RandomName2 | RandomLast2 | RandomName3 | RandomLast3 | RandomName4 | RandomLast4 | RandomName5 | RandomLast5 | 
+1

Ты прибил его. Мне нравится сжатый способ, я использую SQL 2012. – navossoc

+0

@navossoc Конкретный путь определенно проще, так как у вас есть 'rowId', который можно использовать. – Taryn

2

Попробуйте что-то вроде этого

CREATE TABLE #Table1 
    ([uid] int, [name] varchar(4), [diseaseid] int, [intensity] varchar(4)) 
; 

INSERT INTO #Table1 
    ([uid], [name], [diseaseid], [intensity]) 
VALUES (1, 'xxxx', 2, 'low') 
    (1, 'xxxx', 1, 'high'), 

; 

SELECT MAX([uid]) AS [uid] 
     ,MAX([name]) AS [name] 
     ,MAX([diseaseid1]) AS [diseaseid1] 
     ,MAX([intensity1]) AS [intensity1] 
     ,MAX([diseaseid2]) AS [diseaseid2] 
     ,MAX([intensity2]) [intensity2] 
FROM 
(
    SELECT [uid], [name] 
    , CASE WHEN rn=2 THEN NULL ELSE [diseaseid] END AS [diseaseid1] 
    , CASE WHEN rn=2 THEN NULL ELSE [intensity] END AS [intensity1] 
    , CASE WHEN rn=1 THEN NULL ELSE [diseaseid] END AS [diseaseid2] 
    , CASE WHEN rn=1 THEN NULL ELSE [intensity] END AS [intensity2] 
    FROM 
    (
     SELECT [uid], [name], [diseaseid], [intensity], 
     ROW_NUMBER() OVER(PARTITION BY [uid] ORDER BY Name) AS rn 
     FROM #Table1 
    ) T 
) T 
GROUP BY [uid], [name] 
+0

Не совсем то, что мне нужно, но ваш ответ мне очень помог. Благодаря! – navossoc