首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL 動態行轉列 (PIVOT) 實作:以欄位值為輸出欄名 (物品/日期/數量)

     編輯:關於SqlServer

業務需求

來源表 EE:

日期數量物品
1月1日200A
1月1日300A
1月2日100B
1月3日200A

期望輸出:

物品1月1日1月2日1月3日
A5000200
B01000

動態 SQL 實作 (SQL Server)


DECLARE @sql NVARCHAR(MAX) = N'SELECT [物品]';

-- 1. 動態產生彙總欄位清單
SELECT @sql = @sql + N', SUM(CASE [日期] WHEN ''' + [日期] + ''' THEN [數量] ELSE 0 END) AS [' + [日期] + ']'
FROM (SELECT DISTINCT [日期] FROM EE) AS Dates;

-- 2. 完成 GROUP BY 子句
SET @sql = @sql + N' FROM EE GROUP BY [物品]';

-- 3. 執行
EXEC sp_executesql @sql;

關鍵點解析

  1. 動態欄位產生:透過查詢 DISTINCT 日期 迴圈組裝 SUM(CASE...) 運算式,解決「欄名不固定」問題。
  2. 條件彙總:CASE WHEN 日期 = '目標日期' THEN 數量 ELSE 0 END 將長表轉寬表。
  3. sp_executesql:參數化執行動態 SQL,優於 EXEC(@sql) (計畫重用、防注入)。

靜態 PIVOT 寫法 (已知固定日期)


SELECT 物品, 
    ISNULL([1月1日], 0) AS [1月1日],
    ISNULL([1月2日], 0) AS [1月2日],
    ISNULL([1月3日], 0) AS [1月3日]
FROM (
    SELECT 物品, 日期, 數量 FROM EE
) AS SourceTable
PIVOT (
    SUM(數量) FOR 日期 IN ([1月1日], [1月2日], [1月3日])
) AS PivotTable;

進階:日期欄位為 DATETIME 型別時的格式化


-- 動態 SQL 中格式化日期為字串作欄名
SELECT @sql = @sql + N', SUM(CASE CONVERT(VARCHAR(10), [日期], 120) WHEN ''' + CONVERT(VARCHAR(10), [日期], 120) + ''' THEN [數量] ELSE 0 END) AS [' + CONVERT(VARCHAR(10), [日期], 120) + ']'
FROM (SELECT DISTINCT CONVERT(VARCHAR(10), [日期], 120) AS Dt FROM EE) AS Dates;

適用場景

  • 銷售報表:產品 × 月份/門市
  • 考勤統計:員工 × 日期/班別
  • 庫存快照:物料 × 倉庫/日期
  • 任何「長表轉寬表、行標轉列標」需求

結語

動態 SQL 組裝 SUM(CASE...) 是 SQL Server 實作動態 PIVOT 的經典模式,靈活處理不固定欄名。SQL Server 2005+ 亦可使用 PIVOT 運算子 (靜態欄名)。選擇原則:欄名固定用 PIVOT 可讀性佳;欄名動態用動態 SQL。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved