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

DB2 列轉行 (UNPIVOT) 實戰:VALUES + TABLE 函數優雅轉換

     編輯:DB2 教學

業務場景

寬表 SALES_AGG(已彙總):

CREATE TABLE SALES_AGG (
    YEAR INT, Q1 INT, Q2 INT, Q3 INT, Q4 INT
);

YEAR   Q1   Q2   Q3   Q4
2004   20   30   15   10
2005   18   40   12   27

目標:轉為長表格式:

YEAR  QUARTER  RESULTS
2004      1       20
2004      2       30
2004      3       15
2004      4       10
2005      1       18
2005      2       40
2005      3       12
2005      4       27

核心解法:VALUES 建構虛擬表 + TABLE() 函數側向連接

SELECT S.YEAR, V.QUARTER, V.RESULTS
FROM SALES_AGG S,
     TABLE (
         VALUES 
             (1, S.Q1),
             (2, S.Q2),
             (3, S.Q3),
             (4, S.Q4)
     ) AS V(QUARTER, RESULTS);

關鍵機制深度解析

1. VALUES 子句建構行集合

VALUES (1, S.Q1), (2, S.Q2), ... 每個元組對應一行,所有元組欄位數、資料型別必須一致(此處皆為 INT, INT)。

2. TABLE() 將行集合轉為關聯表

TABLE(...) 是 DB2 的表函數,接受標量子查詢或行值建構器,產生一個可被 FROM 引用的虛擬表。

3. 側向關聯

TABLE(...) 內部引用外部表 S 的列(S.Q1 等),這屬於 Lateral Join(側向連接),DB2 隱式支援無需寫 LATERAL 關鍵字。每讀取 SALES_AGG 一行,即執行一次 TABLE(VALUES...) 產生 4 行,再橫向展開。

4. 別名與欄位命名

AS V(QUARTER, RESULTS) 為虛擬表命名並指定欄位別名,供外層 SELECT 使用。

VALUES 虛擬表獨立測試範例

-- 多行多列
SELECT * FROM (VALUES (1,2), (2,3)) AS T(C1, C2);
C1  C2
1   2
2   3

-- 單行單列
SELECT * FROM (VALUES 1) AS A(C1);
C1
1

替代方案:UNION ALL(通用但冗長)

SELECT YEAR, 1 AS QUARTER, Q1 AS RESULTS FROM SALES_AGG
UNION ALL
SELECT YEAR, 2, Q2 FROM SALES_AGG
UNION ALL
SELECT YEAR, 3, Q3 FROM SALES_AGG
UNION ALL
SELECT YEAR, 4, Q4 FROM SALES_AGG;

缺點:掃描基表 4 次,SQL 冗長,維護困難。VALUES+TABLE 只掃描基表一次,效能與可讀性雙贏。

擴展應用:動態欄位數量

若季度欄位不固定,可結合動態 SQL:查詢 SYSCAT.COLUMNS 獲取欄位清單,組裝 VALUES 子句字串,再 PREPARE/EXECUTE。

適用版本提示

  • TABLE(VALUES...) 側向連接語法支援 DB2 9.7+(LUW)。
  • 舊版本需用 UNION ALL 或 CROSS JOIN 系統表模擬。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved