T-SQL Recipes之Dynamic PIVOT and UNPIVOT
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了T-SQL Recipes之Dynamic PIVOT and UNPIVOT相关的知识,希望对你有一定的参考价值。
PIVOT
PIVOT在行转列的时候经常用到,最便捷的方式就是通过示例来理解它的作用。
示例1 Query to Return Select Product Data from AdventureWorks
SELECT 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;
结果:
如果我们想要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;
结果:
从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;
首先看一下打印出来的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
结果:
从示例1到示例3,我们从中了解到如何把复杂的SQL慢慢分解出来,最后在组合在一起。
UNPIVOT
ds
ds
以上是关于T-SQL Recipes之Dynamic PIVOT and UNPIVOT的主要内容,如果未能解决你的问题,请参考以下文章
T-SQL Recipes之Index Defragmentation
T-SQL Recipes之Customized Database Objects
T-SQL Recipes之 Table Variables and Temporary Tables and CTE
翻译Stairway to T-SQL: Beyond The Basics Level 9: Dynamic T-SQL Code
十九curator recipes之PathChildrenCache
翻译:T-SQL进阶:超越基础Level9:动态T—SQL代码(Stairway To T—SQL: Beyond The Basics Level9: Dynamic T—SQL Code);原文地