2012-05-03 23 views
29

Sono molto nuovo in SQL.Informazioni sulla funzione PIVOT in T-SQL

Ho una tabella come questa:

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 

e mi fu detto di ottenere i dati in questo modo

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

ho capito che ho bisogno di usare la funzione PIVOT. Ma non riesco a capirlo chiaramente. Sarebbe di grande aiuto se qualcuno potesse spiegarlo nel caso di cui sopra (o eventuali alternative)

risposta

40

A PIVOT Usato per ruotare i dati da una colonna in più colonne.

Per esempio, ecco uno STATICO Pivot il che significa codificare le colonne che si desidera ruotare:

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 

Ecco un SQL Demo con una versione funzionante.

Questo può essere fatto anche tramite un PIVOT dinamico in cui si crea dinamicamente l'elenco di colonne ed si esegue il 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) 

I risultati per entrambi:

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

Grazie. L'unica cosa che ho bisogno di hard code 'PhaseID' prima di QUOTENAME. destra? –

+1

nel QUOTENAME devi identificare da quale colonna devi ottenere i valori.È questo che stai chiedendo? – Taryn

+2

ok. Fatto. Grazie –

5

Questi sono gli esempi di base più semplici che attraversano gentilmente questo.

SQL SERVER – PIVOT and UNPIVOT Table Examples

Esempio dall'alto link per il tavolo di prodotto:

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 

rende:

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

esempi simili si possono trovare nel post del blog Pivot tables in SQL Server. A simple sample

+1

esempio davvero semplice. Grazie :) –

2

Per impostare errore di compatibilità

uso prima di utilizzare la funzione di rotazione

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

mi era nuovo a questo e io crea un bel post su di esso ... My proble m è stato capire come applicare l'aggregazione correttamente e qui è il mio post: http://jaider.net/posts/1176-pivot-in-sql-server-correct-aggregated-results/

In soluzione @bluefeet, E 'importante ricordare che elementid è la colonna chiave del vostro "invisibile" Group By. Inoltre, è possibile sostituire elementid o aggiungere più colonne, ad esempio userid.

enter image description here