2015-03-26 2 views
0

У меня есть следующая таблица:
Колонка к ряду SQL синтаксис

-------------------------------------------- 
Group Date   Value1 Value2 Value3 
-------------------------------------------- 
A  2014-01-01 10  10  5 
B  2014-01-01 12  20  25 
C  2014-01-01 20  40  50 

Я хочу иметь следующий результат:

------------------------------------------- 
NewCol  A  B  C 
------------------------------------------- 
Value1  10  12  20 
Value2  10  20  40 
Value3  5  25  50 

Как я могу это сделать в SQL Server 2008? Спасибо.

+5

[Поиск на этом сайте в одиночку ......] (http://stackoverflow.com/search?q=sql+server+convert+row+to+column) дает ** 697 ответов ** ... .. –

+0

строка для столбца и столбца для строки. это мой вопрос на самом деле. Как его сочетать? – Haminteu

ответ

1

Для перестановки строк и столбцов, необходимо UNPIVOT (преобразовать столбцы в значение строк), а затем PIVOT (строки в столбцы) на основе результата UNPIVOT.

-- Here is the result 
SELECT * FROM 
(
    -- Unpivot here using CROSS APPLY 
    SELECT [Group], 
    [Values],COLNAMES 
    FROM YOURTABLE 
    CROSS APPLY(VALUES (Value1,'Value1'),(Value2,'Value2'),(Value3,'Value3')) 
    AS COLUMNNAMES([Values],COLNAMES) 
)TAB 
PIVOT 
(
    -- Specify the values to hold in pivoted column 
    MIN([Values]) 
    -- Specify the name of columns 
    FOR [Group] IN([A],[B],[C]) 
)P 
ORDER BY COLNAMES 

ОБРАБОТКА ЗАПРОСА

Вы можете использовать CROSS APPLY для UNPIVOT. Value1 будут столбцами, которые содержат значения в столбце - Value1. 'Value1' (в одиночных кавычках) будет трудно закодированное значение имени столбца (который показан на COLNAMES переменном. Использование CROSS APPLY будет генерировать следующий результат.

enter image description here

Теперь с данными, полученными от CROSS APPLY, вы отправитесь в PIVOT, который образует следующий результат.

enter image description here

Иногда вы не можете знать значения в столбце Group заранее. В таком случае вам необходимо использовать Dynamic Sql.Первым шагом в этом является получение значений в строке Group переменной.

DECLARE @cols NVARCHAR (MAX) 

SELECT @cols = STUFF((SELECT ',' + QUOTENAME([Group]) 
      FROM 
      (
       SELECT distinct [Group] from YOURTABLE 
      ) c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

Теперь используйте PIVOT запрос с Dynamic Sql. Почему мы используем Dynamic Sql, потому что Sql Server не может получить имена столбцов из переменной, если только и не используется Dynamic Sql.

DECLARE @query NVARCHAR(MAX) 
SET @query = ' 
      SELECT * FROM 
      (
       -- Unpivot here using CROSS APPLY 
       SELECT [Group], 
       [Values],COLNAMES 
       FROM YOURTABLE 
       CROSS APPLY(VALUES (Value1,''Value1''),(Value2,''Value2''),(Value3,''Value3'')) 
       AS COLUMNNAMES([Values],COLNAMES) 
      ) x 
      PIVOT 
      (
       -- Specify the values to hold in pivoted column 
       MIN([Values]) 
       -- Get the column names from variable 
       FOR [Group] IN('[email protected]+') 
      ) p    
      ORDER BY COLNAMES;'  

EXEC SP_EXECUTESQL @query 

Надеюсь, вы понимаете понятия и получили результат.
Любые разъяснения, не стесняйтесь спрашивать.

0

Использование PIVOT функция. Это даст вам ответ.

Пример PIVOT Функция

SELECT <non-pivoted column>, 
     [first pivoted column] AS <column name>, 
     [second pivoted column] AS <column name>, 
     ... 
     [last pivoted column] AS <column name> 
    FROM 
     (<SELECT query that produces the data>) 
     AS <alias for the source query> 
    PIVOT 
    (
     <aggregation function>(<column being aggregated>) 
    FOR 
    [<column that contains the values that will become column headers>] 
     IN ([first pivoted column], [second pivoted column], 
     ... [last pivoted column]) 
    ) AS <alias for the pivot table> 
    <optional ORDER BY clause>; 

Проверить этот Reference братан: Click Here

+0

Спасибо за ответ. Но я не понимаю. – Haminteu

0

Вам нужно UNPIVOT:

DECLARE @t TABLE 
    (
     G CHAR(1) , 
     V1 INT , 
     V2 INT , 
     V3 INT 
    ) 

INSERT INTO @t 
VALUES ('A', 10, 10, 5), 
     ('B', 12, 20, 25), 
     ('C', 20, 40, 50); 
WITH cte1 
      AS (SELECT * 
       FROM  @t 
       WHERE G = 'A' 
      ), 
     cte2 
      AS (SELECT * 
       FROM  @t 
       WHERE G = 'B' 
      ), 
     cte3 
      AS (SELECT * 
       FROM  @t 
       WHERE G = 'C' 
      ) 
    SELECT u1.v , 
      u1.a , 
      u2.b , 
      u3.c 
    FROM (SELECT * 
       FROM  cte1 UNPIVOT(a FOR v IN ([V1], [V2], [V3])) u 
      ) u1 
      JOIN (SELECT * 
        FROM  cte2 UNPIVOT(b FOR v IN ([V1], [V2], [V3])) u 
       ) u2 ON u1.v = u2.v 
      JOIN (SELECT * 
        FROM  cte3 UNPIVOT(c FOR v IN ([V1], [V2], [V3])) u 
       ) u3 ON u2.v = u3.v 

Выход:

v a b c 
V1 10 12 20 
V2 10 20 40 
V3 5 25 50 
+0

Использование 'Cross apply' вы можете просто решить –

1

Вы можете использовать оператор PIVOT. Смотрите подробности ниже:

select 'Value1' NewCol, A, B, C 
from (select [Group], Value1 Value from YourTable) g 
pivot (
    max(g.Value) 
    for g.[Group] in (A, B, C)) p 
union all 
select 'Value2', A, B, C 
from (select [Group], Value2 Value from YourTable) g 
pivot (
    max(g.Value) 
    for g.[Group] in (A, B, C)) p 
union all 
select 'Value3', A, B, C 
from (select [Group], Value3 Value from YourTable) g 
pivot (
    max(g.Value) 
    for g.[Group] in (A, B, C)) p 

Или Вы можете комбинировать PIVOT и UNPIVOT операторов:

select NewCol, A, B, C 
from (
    select * 
    from YourTable 
    unpivot (
    Value 
    for NewCol in (Value1, Value2, Value3) 
) up 
) up 
pivot (
    max(Value) 
    for [Group] in (A, B, C) 
) p