2012-05-03 1 views
29

Я очень новичок в SQL.Понимание функции PIVOT в T-SQL

У меня есть таблица вроде этого:

ID | TeamID | UserID | ElementID | PhaseID | Effort 
----------------------------------------------------- 
1 | 1 | 1  | 3  | 5  | 6.74 
2 | 1 | 1  | 3  | 6  | 8.25 
3 | 1 | 1  | 4  | 1  | 2.23 
4 | 1 | 1  | 4  | 5  | 6.8 
5 | 1 | 1  | 4  | 6  | 1.5 

И мне сказали, чтобы получить данные, как этот

ElementID | PhaseID1 | PhaseID5 | PhaseID6 
-------------------------------------------- 
    3  | NULL | 6.74 | 8.25 
    4  | 2.23 | 6.8 | 1.5 

Я понимаю, что нужно использовать функцию PIVOT. Но я не могу понять это ясно. Было бы очень полезно, если кто-нибудь сможет объяснить это в приведенном выше случае. (Или любые альтернативы, если таковые имеются)

ответ

40

PIVOT используемый для поворота данных из одного столбца в несколько столбцов.

Для примера здесь является STATIC Pivot означает, что вы жесткий код столбцы, которые вы хотите, чтобы повернуть:

create table temp 
(
    id int, 
    teamid int, 
    userid int, 
    elementid int, 
    phaseid int, 
    effort decimal(10, 5) 
) 

insert into temp values (1,1,1,3,5,6.74) 
insert into temp values (2,1,1,3,6,8.25) 
insert into temp values (3,1,1,4,1,2.23) 
insert into temp values (4,1,1,4,5,6.8) 
insert into temp values (5,1,1,4,6,1.5) 

select elementid 
    , [1] as phaseid1 
    , [5] as phaseid5 
    , [6] as phaseid6 
from 
(
    select elementid, phaseid, effort 
    from temp 
) x 
pivot 
(
    max(effort) 
    for phaseid in([1], [5], [6]) 
)p 

Вот SQL Demo с рабочей версией.

Это также можно сделать с помощью динамического PIVOT, где вы динамически создаете список столбцов и выполняете PIVOT.

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX); 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.phaseid) 
      FROM temp c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT elementid, ' + @cols + ' from 
      (
       select elementid, phaseid, effort 
       from temp 
      ) x 
      pivot 
      (
       max(effort) 
       for phaseid in (' + @cols + ') 
      ) p ' 


execute(@query) 

Результаты для обоих:

ELEMENTID PHASEID1 PHASEID5 PHASEID6 
3   Null  6.74  8.25 
4   2.23  6.8   1.5 
+1

Спасибо. Единственное, что мне нужно для жесткого кода 'PhaseID' перед QUOTENAME. правильно? –

+1

в QUOTENAME вам нужно определить, в какой колонке вам нужны значения.Это то, что вы просите? – Taryn

+2

ok. Понял. Спасибо –

5

Это самый простой пример поворота, который проходит через это.

SQL SERVER – PIVOT and UNPIVOT Table Examples

Пример сверху ссылки для продукта таблице:

SELECT PRODUCT, FRED, KATE 
FROM (
SELECT CUST, PRODUCT, QTY 
FROM Product) up 
PIVOT (SUM(QTY) FOR CUST IN (FRED, KATE)) AS pvt 
ORDER BY PRODUCT 

оказывает:

PRODUCT FRED KATE 
-------------------- 
BEER  24 12 
MILK  3  1 
SODA NULL  6 
VEG NULL  5 

Подобные примеры можно найти в блоге Pivot tables in SQL Server. A simple sample

+1

действительно простой пример. Спасибо :) –

2

Чтобы установить ошибки совместимости

использование этого перед использованием функции поворота

ALTER DATABASE [dbname] SET COMPATIBILITY_LEVEL = 100 
0
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>; 

USE AdventureWorks2008R2 ; 
GO 
SELECT DaysToManufacture, AVG(StandardCost) AS AverageCost 
FROM Production.Product 
GROUP BY DaysToManufacture; 

    DaysToManufacture   AverageCost 
0       5.0885 
1       223.88 
2       359.1082 
4       949.4105 

    -- Pivot table with one row and five columns 
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days, 
[0], [1], [2], [3], [4] 
FROM 
(SELECT DaysToManufacture, StandardCost 
    FROM Production.Product) AS SourceTable 
PIVOT 
(
AVG(StandardCost) 
FOR DaysToManufacture IN ([0], [1], [2], [3], [4]) 
) AS PivotTable; 




Here is the result set. 
Cost_Sorted_By_Production_Days 0   1   2   3  4  
AverageCost      5.0885 223.88 359.1082 NULL 949.4105 
2

Я новичок в этом и я создайте хороший пост об этом ... Мой провал м были понимание того, как правильно применять агрегацию и вот мой пост: http://jaider.net/posts/1176-pivot-in-sql-server-correct-aggregated-results/

В @bluefeet раствора Важно отметить, что elementid является ключевым столбцом вашего «невидимого» Group By. Кроме того, вы можете заменить elementid или добавить дополнительные столбцы, такие как userid.

enter image description here

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