2012-05-03 23 views
29

Jestem bardzo nowy w SQL.Opis funkcji PIVOT w T-SQL

Mam tabeli jak poniżej:

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 

i powiedziano mi, aby uzyskać dane jak ten

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

Rozumiem, że muszę korzystać z funkcji obrotu. Ale nie potrafię tego jasno zrozumieć. Byłoby bardzo pomocne, gdyby ktoś mógł to wyjaśnić w powyższym przypadku (lub dowolne inne alternatywy, jeśli takie istnieją).

Odpowiedz

40

PIVOT używany aby obrócić dane z jednej kolumny do wielu kolumn.

Dla przykładu tutaj jest statyczną pivot czyli ci ciężko kodem kolumn, które chcesz obrócić:

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 

Oto SQL Demo w wersji roboczej.

Można to również zrobić za pomocą dynamicznego PIVOT, w którym dynamicznie tworzy się listę kolumn i wykonuje się 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) 

Wyniki dla obu:

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

Dzięki, mam to. Jedyne, czego potrzebuję, aby zakodować "PhaseID" przed QUOTENAME. dobrze? –

+1

w QUOTENAME musisz określić kolumnę, z której chcesz pobrać wartości.Czy o to pytasz? – Taryn

+2

ok. Rozumiem. Dzięki –

5

To jest bardzo prosty przykład przestawny, który należy przejść przez to.

SQL SERVER – PIVOT and UNPIVOT Table Examples

przykład z góry połączenia na parametry:

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 

czyni:

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

Podobne przykłady można znaleźć w blogu Pivot tables in SQL Server. A simple sample

+1

Bardzo prosty przykład. Dzięki :) –

2

Aby ustawić błędach Zgodność

użycie tego przed użyciem funkcji pivot

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

jestem nowy w tym i ja stwórz fajny post na ten temat ... Mój problem m został zrozumienia, jak zastosować agregację prawidłowo i tu jest mój post: http://jaider.net/posts/1176-pivot-in-sql-server-correct-aggregated-results/

W roztworze @bluefeet, ważne jest, aby wspomnieć, że elementid jest kluczem kolumna swoją „niewidzialne” Group By. Dodatkowo można zastąpić elementid lub dodać więcej kolumn, takich jak userid.

enter image description here