Use PIVOT and UNPIVOT

 

Applies to: Yes SQL Server (all supported versions)  YesAzure SQL database  YesAzure SQL managed instance  YesAzure Synapse Analytics  Yesparallel data warehouse

You can use the  PIVOT and  UNPIVOT relational operator to change a table-valued expression to another table. PIVOT Rotate table-valued expressions by converting the unique value of one column in the expression to multiple columns in the output. PIVOT Run aggregation when you need to perform aggregation on all remaining column values ​​needed for the final output. Contrary to what PIVOT does, UNPIVOT it rotates the columns of a table-valued expression to column values.

PIVOT The provided SELECT...CASE syntax is simpler and more readable than the syntax specified in a series of complex  statements. For PIVOT a complete description of the  syntax, see  FROM (Transact-SQL) .

grammar

The following syntax summarizes how to use  PIVOT operators.

copy

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>;  

Remarks

UNPIVOT The column identifier in the clause must follow the catalog ordering rules. For SQL databases, the collation is always  SQL_Latin1_General_CP1_CI_AS. For databases partly included in SQL Server, the collation is always  Latin1_General_100_CI_AS_KS_WS_SC. If you merge this column with other columns, you need the collate clause ( COLLATE DATABASE_DEFAULT) to avoid conflicts.

Simple PIVOT example

The following code example generates a table with two columns and four rows.

SQL replication

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

Here is the result set:

copy

DaysToManufacture AverageCost
----------------- -----------
0                 5.0885
1                 223.88
2                 359.1082
4                 949.4105

There is no DaysToManufacture product defined  as 3.

The following code shows the same result, which is pivoted so that the  DaysToManufacture values ​​become column headings. Providing a column represents San  [3] days, even if the result is  NULL.

SQL replication

-- 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:

copy

Cost_Sorted_By_Production_Days 0           1           2           3           4         
------------------------------ ----------- ----------- ----------- ----------- -----------
AverageCost                    5.0885      223.88      359.1082    NULL        949.4105

Complex PIVOT example

If you want to generate a cross-tab report to summarize data, you may often find  PIVOT it useful. For example, suppose you need PurchaseOrderHeader to query a AdventureWorks2014 table in a  sample database  to determine the number of purchase orders placed by certain employees. The following query provides this report (sorted by vendor).

SQL replication

USE AdventureWorks2014;  
GO  
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5  
FROM   
(SELECT PurchaseOrderID, EmployeeID, VendorID  
FROM Purchasing.PurchaseOrderHeader) p  
PIVOT  
(  
COUNT (PurchaseOrderID)  
FOR EmployeeID IN  
( [250], [251], [256], [257], [260] )  
) AS pvt  
ORDER BY pvt.VendorID;  

The following is a partial result set.

copy

VendorID    Emp1        Emp2        Emp3        Emp4        Emp5  
----------- ----------- ----------- ----------- ----------- -----------
1492        2           5           4           4           4
1494        2           5           4           5           4
1496        2           4           4           5           5
1498        2           5           4           4           4
1500        3           4           4           5           4

EmployeeID The results returned by this nested select statement will be pivoted on the  columns.

SQL replication

SELECT PurchaseOrderID, EmployeeID, VendorID  
FROM PurchaseOrderHeader;  

EmployeeID The unique value returned by the column becomes a field in the final result set. Accordingly, each pivot specified in clause  EmployeeID numbers are columns: In this example, for employees  250, 251, 256, 257 and  260PurchaseOrderID The column is used as the value column, and the columns returned in the final output (called grouping columns) will be grouped according to this column. In this example, the COUNT grouping columns are aggregated by  function. Note that the system displays a warning message to indicate that  any NULL values ​​in the column were COUNT not considered when  calculating for each employee  PurchaseOrderID.

 important

If the aggregation function is  PIVOT used with, any null values ​​that appear in the value column will not be considered when calculating the aggregation.

Example of inverse perspective

It  PIVOT is almost the opposite of the operation performed, UNPIVOT rotating the columns to rows. Suppose in the example above is generated is stored as a table in the database  pvt, and you need to column identifiers  Emp1, Emp2, Emp3, Emp4 and  Emp5 the rotation value of the row corresponding to a particular vendor. Therefore, the other two columns must be identified. The column that contains the column value ( Emp1, Emp2...) Employeeto be rotated is called , and the column  that retains the existing value under the column to be rotated is called  Orders. These columns correspond to pivot_column and value_column in the Transact-SQL definition, respectively. The following is the query.

SQL replication

-- Create the table and insert values as portrayed in the previous example.  
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,  
    Emp3 int, Emp4 int, Emp5 int);  
GO  
INSERT INTO pvt VALUES (1,4,3,5,4,4);  
INSERT INTO pvt VALUES (2,4,1,5,5,5);  
INSERT INTO pvt VALUES (3,4,3,5,4,4);  
INSERT INTO pvt VALUES (4,4,2,5,5,4);  
INSERT INTO pvt VALUES (5,5,1,5,5,5);  
GO  
-- Unpivot the table.  
SELECT VendorID, Employee, Orders  
FROM   
   (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5  
   FROM pvt) p  
UNPIVOT  
   (Orders FOR Employee IN   
      (Emp1, Emp2, Emp3, Emp4, Emp5)  
)AS unpvt;  
GO  

The following is a partial result set.

copy

VendorID    Employee    Orders
----------- ----------- ------
1            Emp1       4
1            Emp2       3 
1            Emp3       5
1            Emp4       4
1            Emp5       4
2            Emp1       4
2            Emp2       1
2            Emp3       5
2            Emp4       5
2            Emp5       5
...

Please note that it UNPIVOT is not exactly  PIVOT the reverse operation. PIVOT Perform aggregation and merge multiple possible lines into one line in the output. UNPIVOT The result of the original table-valued expression is not reproduced because the rows have been merged. In addition, UNPIVOT the NULL value in the input disappears in the output. If the value disappears, PIVOT it means that the original NULL value may already exist in the input before performing the  operation.

 The Sales.vSalesPersonSalesByFiscalYears view in the AdventureWorks2012 sample database  will use  PIVOT to return the total sales of each salesperson in each fiscal year. To write a view script in SQL Server Management Studio, please find  the view corresponding to the AdventureWorks2012 database in the "View" folder in the "Object Explorer"  . Right-click the view name, and then select "Script View As".

Guess you like

Origin blog.csdn.net/allway2/article/details/108654926