Sök…


Syntax

  • VÄLJ <non-pivoted column> ,
    [första svängda kolumnen] AS <column name> ,
    [andra svängd kolumn] AS <column name> ,
    ...
    [senast svängd kolumn] AS <column name>
    FRÅN
    ( <SELECT query that produces the data> )
    AS <alias for the source query>
    SVÄNGA
    (
    <aggregation function> ( <column being aggregated> )
    FÖR
    [ <column that contains the values that will become column headers> ]
    IN ([första svängd kolumn], [andra svängd kolumn],
    ... [sista svängda kolumnen))
    ) AS <alias for the pivot table> <optional ORDER BY clause> ;

Anmärkningar

Med hjälp av PIVOT- och UNPIVOT-operatörer omvandlar du en tabell genom att flytta raderna (kolumnvärden) på en tabell till kolumner och vice versa. Som en del av denna transformation kan aggregeringsfunktioner tillämpas på tabellvärdena.

Simple Pivot - Statiska kolumner

Använd artikelförsäljningstabell från exempeldatabas , låt oss beräkna och visa det totala kvantitet som vi sålde för varje produkt.

Detta kan enkelt göras med en grupp av, men låt oss anta att vi "roterar" vår resultattabell på ett sätt som för varje produkt-id har vi en kolumn.

SELECT [100], [145]
  FROM (SELECT ItemId , Quantity
          FROM #ItemSalesTable
       ) AS pivotIntermediate
 PIVOT (   SUM(Quantity)
           FOR ItemId IN ([100], [145])
       ) AS pivotTable

Eftersom våra "nya" kolumner är siffror (i källtabellen), måste vi kvadrera parenteser []

Detta ger oss en output som

100 145
45 18

Enkel PIVOT & UNPIVOT (T-SQL)

Nedan följer ett enkelt exempel som visar genomsnittsprisets pris för varje artikel per veckodag.

Först och främst antar att vi har en tabell som håller dagliga register över alla artiklar priser.

CREATE TABLE tbl_stock(item NVARCHAR(10), weekday NVARCHAR(10), price INT);

INSERT INTO tbl_stock VALUES 
('Item1', 'Mon', 110), ('Item2', 'Mon', 230), ('Item3', 'Mon', 150), 
('Item1', 'Tue', 115), ('Item2', 'Tue', 231), ('Item3', 'Tue', 162), 
('Item1', 'Wed', 110), ('Item2', 'Wed', 240), ('Item3', 'Wed', 162), 
('Item1', 'Thu', 109), ('Item2', 'Thu', 228), ('Item3', 'Thu', 145), 
('Item1', 'Fri', 120), ('Item2', 'Fri', 210), ('Item3', 'Fri', 125),
('Item1', 'Mon', 122), ('Item2', 'Mon', 225), ('Item3', 'Mon', 140),
('Item1', 'Tue', 110), ('Item2', 'Tue', 235), ('Item3', 'Tue', 154),
('Item1', 'Wed', 125), ('Item2', 'Wed', 220), ('Item3', 'Wed', 142);

Tabellen ska se ut som nedan:

+========+=========+=======+
|   item | weekday | price |
+========+=========+=======+
|  Item1 |    Mon  |   110 |
+--------+---------+-------+
|  Item2 |    Mon  |   230 |
+--------+---------+-------+
|  Item3 |    Mon  |   150 |
+--------+---------+-------+
|  Item1 |    Tue  |   115 |
+--------+---------+-------+
|  Item2 |    Tue  |   231 |
+--------+---------+-------+
|  Item3 |    Tue  |   162 |
+--------+---------+-------+
|          . . .           |
+--------+---------+-------+
|  Item2 |    Wed  |   220 |
+--------+---------+-------+
|  Item3 |    Wed  |   142 |
+--------+---------+-------+

För att utföra aggregation vilket är att hitta det genomsnittliga priset per enhet för varje veckodag, kommer vi att använda relationsoperator PIVOT att rotera kolumnen weekday av tabellvärdes uttryck i aggregerade rad värden som nedan:

SELECT * FROM tbl_stock
PIVOT ( 
    AVG(price) FOR weekday IN ([Mon], [Tue], [Wed], [Thu], [Fri])
) pvt;

Resultat:

+--------+------+------+------+------+------+
|  item  |  Mon |  Tue |  Wed |  Thu |  Fri |
+--------+------+------+------+------+------+
|  Item1 |  116 |  112 |  117 |  109 |  120 |
|  Item2 |  227 |  233 |  230 |  228 |  210 |
|  Item3 |  145 |  158 |  152 |  145 |  125 |
+--------+------+------+------+------+------+

Slutligen, för att utföra omvänd operation av PIVOT , kan vi använda den relationella operatören UNPIVOT att rotera kolumner i rader enligt nedan:

SELECT * FROM tbl_stock
PIVOT ( 
    AVG(price) FOR weekday IN ([Mon], [Tue], [Wed], [Thu], [Fri])
) pvt
UNPIVOT ( 
    price FOR weekday IN ([Mon], [Tue], [Wed], [Thu], [Fri])
) unpvt;

Resultat:

+=======+========+=========+
|  item |  price | weekday |
+=======+========+=========+
| Item1 |    116 |     Mon |
+-------+--------+---------+
| Item1 |    112 |     Tue |
+-------+--------+---------+
| Item1 |    117 |     Wed |
+-------+--------+---------+
| Item1 |    109 |     Thu |
+-------+--------+---------+
| Item1 |    120 |     Fri |
+-------+--------+---------+
| Item2 |    227 |     Mon |
+-------+--------+---------+
| Item2 |    233 |     Tue |
+-------+--------+---------+
| Item2 |    230 |     Wed |
+-------+--------+---------+
| Item2 |    228 |     Thu |
+-------+--------+---------+
| Item2 |    210 |     Fri |
+-------+--------+---------+
| Item3 |    145 |     Mon |
+-------+--------+---------+
| Item3 |    158 |     Tue |
+-------+--------+---------+
| Item3 |    152 |     Wed |
+-------+--------+---------+
| Item3 |    145 |     Thu |
+-------+--------+---------+
| Item3 |    125 |     Fri |
+-------+--------+---------+

Dynamisk PIVOT

Ett problem med PIVOT frågan är att du måste ange alla värden i IN valet om du vill se dem som kolumner. Ett snabbt sätt att kringgå detta problem är att skapa ett dynamiskt IN-val som gör din PIVOT dynamisk.

För demonstration kommer vi att använda en Books i en Bookstore databas. Vi antar att tabellen är ganska de-normaliserad och har följande kolumner

Table: Books
-----------------------------
BookId (Primary Key Column)
Name
Language
NumberOfPages
EditionNumber
YearOfPrint
YearBoughtIntoStore
ISBN
AuthorName
Price
NumberOfUnitsSold

Skapningsskriptet för tabellen kommer att vara som:

CREATE TABLE [dbo].[BookList](
      [BookId] [int] NOT NULL,
      [Name] [nvarchar](100) NULL,
      [Language] [nvarchar](100) NULL,
      [NumberOfPages] [int] NULL,
      [EditionNumber] [nvarchar](10) NULL,
      [YearOfPrint] [int] NULL,
      [YearBoughtIntoStore] [int] NULL,
[NumberOfBooks] [int] NULL,
[ISBN] [nvarchar](30) NULL,
      [AuthorName] [nvarchar](200) NULL,
      [Price] [money] NULL,
      [NumberOfUnitsSold] [int] NULL,
 CONSTRAINT [PK_BookList] PRIMARY KEY CLUSTERED
(
      [BookId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Om vi nu måste fråga i databasen och räkna ut antalet böcker på engelska, ryska, tyska, hindi, latinska språk som köpts in i bokhandeln varje år och presentera vår produktion i ett litet rapportformat, kan vi använda PIVOT-fråga så här

SELECT * FROM
  (
   SELECT YearBoughtIntoStore AS [Year Bought],[Language], NumberOfBooks
   FROM BookList
  ) sourceData 
 PIVOT
  (
  SUM(NumberOfBooks)
  FOR [Language] IN (English, Russian, German, Hindi, Latin)
  ) pivotrReport

Speciellt fall är när vi inte har en fullständig lista över språk, så vi använder dynamisk SQL som nedan

DECLARE @query VARCHAR(4000)
DECLARE @languages VARCHAR(2000)
SELECT @languages =
        STUFF((SELECT DISTINCT '],['+LTRIM([Language])FROM [dbo].[BookList]
        ORDER BY '],['+LTRIM([Language]) FOR XML PATH('') ),1,2,'') + ']'
SET @query=
'SELECT * FROM
  (SELECT YearBoughtIntoStore AS [Year Bought],[Language],NumberOfBooks
   FROM BookList) sourceData
PIVOT(SUM(NumberOfBooks)FOR [Language] IN ('+ @languages +')) pivotrReport' EXECUTE(@query)


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow