寬表 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
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);
VALUES (1, S.Q1), (2, S.Q2), ... 每個元組對應一行,所有元組欄位數、資料型別必須一致(此處皆為 INT, INT)。
TABLE(...) 是 DB2 的表函數,接受標量子查詢或行值建構器,產生一個可被 FROM 引用的虛擬表。
TABLE(...) 內部引用外部表 S 的列(S.Q1 等),這屬於 Lateral Join(側向連接),DB2 隱式支援無需寫 LATERAL 關鍵字。每讀取 SALES_AGG 一行,即執行一次 TABLE(VALUES...) 產生 4 行,再橫向展開。
AS V(QUARTER, RESULTS) 為虛擬表命名並指定欄位別名,供外層 SELECT 使用。
-- 多行多列
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
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 系統表模擬。