SELECT * FROM
(SELECT TOP (1000) *
FROM [HerPeisTJTLTJZX].[dbo].[viDd]
WHERE nian ='2023' and yue='4'
)A
SELECT org,[1],[2],[3],[4],[5],[6],[7]
FROM [HerPeisTJTLTJZX].[dbo].[viDd]
PIVOT
(
SUM(rsvCnt) for [yao] in ([1],[2],[3],[4],[5],[6],[7])
) TBL
where zhou=datepart(wk,'2023-04-17') and org is not null
and ([20230405] is not null)
SELECT org,[20230403],[20230404],[20230405]
FROM [HerPeisTJTLTJZX].[dbo].[viDd]
PIVOT
(
SUM(rsvCnt) for [ddStr] in ([20230403],[20230404],[20230405])--select dd from [HerPeisTJTLTJZX].[dbo].[viDd] WHERE yy ='2023' and mm ='4' )
) TBL
where org is not null
and ([20230405] is not null)
set datefirst 1
select datepart(weekday, getdate())
select datepart(dd, getdate())
PIVOT函數
將商品類型列中的值轉換爲列標題
SELECT 商店名,[短袖],[褲子]
FROM 銷售
PIVOT(SUM(銷售量) FOR 商品類型 IN ([短袖],[褲子])) a
商店名 短袖 褲子
安踏 20 56
李寧 30 60
安踏 61 60
李寧 40 80
安踏 55 78
李寧 50 90
明明SELECT語句中有商店名,怎麼沒有對商店名進行分組,爲什麼安踏和李寧出現三次,安踏短袖的銷售數量不顯示總和136,是不是有點像僅僅進行了行列轉換?
這實際上與SQL語句的執行順序有關,銷售表中包含四列,分別爲商店名,商品類型,銷售量和日期,上述語句執行步驟類似如下:
1. 首先,對非聚合列進行分組,然後對聚合列進行統計
商店名,商品類型,銷售日期爲非聚合列,銷售量爲聚合列,商品類型既是非聚合列也是要成爲列標題的列
SELECT 商店名,商品類型,銷售日期,SUM(銷售量) FROM 銷售 GROUP BY 商店名,商品類型, 銷售日期
2.其次,將要成爲列標題的值轉化爲透視列,值爲聚合函數對應的值
具體爲將商品類型列中的值轉換爲列標題,值爲SUM(銷售量)對應的值
3. 最後,從這個表中篩選出列
上述語句相當於篩選出商店名,短袖和褲子這三列
SELECT 商店名,日期,[短袖],[褲子]
FROM 銷售
PIVOT(SUM(銷售量) FOR 商品類型 IN ([短袖],[褲子])) a
商店名 日期 短袖 褲子
安踏 2021-04-27 20 56
李寧 2021-04-27 30 60
安踏 2021-04-28 61 60
李寧 2021-04-28 40 80
安踏 2021-04-29 55 78
李寧 2021-04-29 50 90
SELECT 商店名,[短袖],[褲子] FROM 銷售 PIVOT(SUM(銷售量) FOR 商品類型 IN ([短袖],[褲子])) a 和 SELECT 商店名,日期,[短袖],[褲子] FROM 銷售 PIVOT(SUM(銷售量) FOR 商品類型 IN ([短袖],[褲子])) a本質上是一樣的,只是最後篩選出的列不同,換句話說PIVOT函數會對源表中除聚合列以外的所有列進行分組GROUP BY,即使SELECT語句中沒有出現一些非聚合列
爲了實現這段時間內各個商店各商品類型銷售總額,需要在源表上進行調整
統計這段時間內各個商店各商品類型銷售總額,並將商品類型列中的值轉換爲列標題
SELECT 商店名,[短袖],[褲子]
FROM (SELECT 商店名,商品類型,銷售量 FROM 銷售) b
PIVOT(SUM(銷售量) FOR 商品類型 IN ([短袖],[褲子])) a
商店名 短袖 褲子
安踏 136 194
李寧 120 230
綜上,無論是利用CASE還是PIVOT進行透視功能,需要搞清楚是僅僅要實現行列轉換,還是需要分組統計後再進行行列轉換,不同的需求SQL語句會有差異,另外,對同一需求CASE和PIVOT的思路也是存在差異的
SQL SERVER PIVOT操作
PIVOT和UNPIVOT
PIVOT 通過將表達式中的一個列的唯一值轉換爲輸出中的多列(即行轉列),來輪替表值表達式。PIVOT 在需要對最終輸出所需的所有剩餘列值執行聚合時運行聚合。與 PIVOT 執行的操作相反,UNPIVOT 將表值表達式的列輪換爲行(即列轉行)。
但是需要注意得是,UNPIVOT 並不完全是 PIVOT 的逆操作。PIVOT 執行聚合,並將多個可能的行合併爲輸出中的一行。UNPIVOT 不重現原始表值表達式的結果,因爲行已被合併。
-- PIVOT 語法
SELECT <非透視的列>,
[第一個透視的列] AS <列名稱>,
[第二個透視的列] AS <列名稱>,
...
[最後一個透視的列] AS <列名稱>,
FROM
(<生成數據的 SELECT 查詢>)
AS <源查詢的別名>
PIVOT
(
<聚合函數>(<要聚合的列>)
FOR
[<包含要成爲列標題的值的列>]
IN ( [第一個透視的列], [第二個透視的列],
... [最後一個透視的列])
) AS <透視表的別名>
<可選的 ORDER BY 子句>;