当前位置:Gxlcms > 数据库问题 > T-SQL Recipes之Dynamic PIVOT and UNPIVOT

T-SQL Recipes之Dynamic PIVOT and UNPIVOT

时间:2021-07-01 10:21:17 帮助过:3人阅读

PRODUCT.Name AS product_name , PRODUCT.Color AS product_color , PRODUCT_INVENTORY.LocationID , PRODUCT.ReorderPoint , PRODUCT_INVENTORY.Quantity AS product_quantity FROM Production.Product PRODUCT LEFT JOIN Production.ProductInventory PRODUCT_INVENTORY ON PRODUCT.ProductID = PRODUCT_INVENTORY.ProductID; View Code

结果:

  技术分享

如果我们想要product_coor 在列里面显示每个产品的数量呢?这时候PIVOT就出场了

示例2:Common Use of PIVOT to Report on Products by Color

技术分享
WITH    PRODUCT_DATA
          AS ( SELECT   PRODUCT.Name AS product_name ,
                        PRODUCT.Color AS product_color ,
                        PRODUCT.ReorderPoint ,
                        PRODUCT_INVENTORY.Quantity AS product_quantity
               FROM     Production.Product PRODUCT
                        LEFT JOIN Production.ProductInventory PRODUCT_INVENTORY ON PRODUCT.ProductID = PRODUCT_INVENTORY.ProductID
             )
    SELECT  *
    FROM    PRODUCT_DATA PIVOT
( SUM(product_quantity) FOR product_color IN ( [Black], [Blue], [Grey],
                                               [Multi], [Red], [Silver],
                                               [Silver/Black], [White],
                                               [Yellow] ) ) PIVOT_DATA;
View Code

结果:

技术分享

从SQL中可以看出PIVOT有两个步骤

  • An aggregate function, which will aggregate if multiple values exist. In the initial
    SELECT statement that returns product data, there were many duplicate rows. This
    example uses SUM whenever this occurs, which will add up product quantities if there
    are multiple rows with the same product name.

  • A value list for all values that will be changed from row data into column headers. In
    this case, the list is of colors from Product.Color .

PS:虽然解决了行转列的问题,但这个时候,我们应该知道color里面到底有多少条唯一的数据,如果在我们不知的情况下,如何解决呢?这个时候动态SQL就来了。

示例3:Common Use of PIVOT to Report on Products by Color

技术分享
USE AdventureWorks2014;
GO

DECLARE @sql_command NVARCHAR(MAX);
DECLARE @sql_colors NVARCHAR(1000);

SET @sql_command = 
WITH    PRODUCT_DATA
          AS ( SELECT   PRODUCT.Name AS product_name ,
                        PRODUCT.Color AS product_color ,
                        PRODUCT.ReorderPoint ,
                        PRODUCT_INVENTORY.Quantity AS product_quantity
               FROM     Production.Product PRODUCT
                        LEFT JOIN Production.ProductInventory PRODUCT_INVENTORY ON PRODUCT.ProductID = PRODUCT_INVENTORY.ProductID
             )
    SELECT  *
    FROM    PRODUCT_DATA PIVOT
( SUM(product_quantity) FOR product_color IN (;
WITH    colorlist
          AS ( SELECT DISTINCT
                        Product.Color AS color_name
               FROM     Production.Product
               WHERE    Product.Color IS NOT NULL
             )
    SELECT  @sql_colors = ISNULL(@sql_colors, N‘‘) + N,
            + QUOTENAME(color_name)
    FROM    colorlist;

SET @sql_colors = STUFF(@sql_colors, 1, 1, ‘‘);

SET @sql_command = @sql_command + @sql_colors + N )) PIVOT_DATA;

PRINT @sql_command;
EXEC sp_executesql @sql_command;
View Code

首先看一下打印出来的SQL:

技术分享
WITH    PRODUCT_DATA
          AS ( SELECT   PRODUCT.Name AS product_name ,
                        PRODUCT.Color AS product_color ,
                        PRODUCT.ReorderPoint ,
                        PRODUCT_INVENTORY.Quantity AS product_quantity
               FROM     Production.Product PRODUCT
                        LEFT JOIN Production.ProductInventory PRODUCT_INVENTORY ON PRODUCT.ProductID = PRODUCT_INVENTORY.ProductID
             )
    SELECT  *
    FROM    PRODUCT_DATA PIVOT
( SUM(product_quantity) FOR product_color IN ( [Black], [Blue], [Grey],
                                               [Multi], [Red], [Silver],
                                               [Silver/Black], [White],
                                               [Yellow] ) ) PIVOT_DATA
View Code

结果:

技术分享

从示例1到示例3,我们从中了解到如何把复杂的SQL慢慢分解出来,最后在组合在一起。

UNPIVOT

 

ds

ds

 

T-SQL Recipes之Dynamic PIVOT and UNPIVOT

标签:

人气教程排行