首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Oracle SQL 行列轉換:將月份-日期明細轉為寬表

     編輯:程式設計綜合問答

問題場景

原始表結構:月份, 日期, 行走公里數,每行記錄某月某日的公里數。需轉換為:月份, 1日, 2日, ..., 31日 的寬表,缺失日期填 0。

標準解法:DECODE + GROUP BY

SELECT (月份 || '月') AS 月份,
       SUM(DECODE(日期, 1, 行走公里數, 0)) AS "1日",
       SUM(DECODE(日期, 2, 行走公里數, 0)) AS "2日",
       SUM(DECODE(日期, 3, 行走公里數, 0)) AS "3日",
       -- ... 繼續到 31
       SUM(DECODE(日期, 31, 行走公里數, 0)) AS "31日"
FROM   表名
GROUP BY 月份
ORDER BY 月份;

進階寫法:PIVOT (Oracle 11g+)

SELECT *
FROM   (
  SELECT 月份, 日期, 行走公里數 FROM 表名
)
PIVOT (
  SUM(行走公里數) FOR 日期 IN (1 AS "1日", 2 AS "2日", ..., 31 AS "31日")
)
ORDER BY 月份;

關鍵點

  • DECODE(日期, n, 值, 0) 實現「條件求和」:只有當日期 = n 時累加公里數,否則加 0。
  • GROUP BY 月份 將同一月份的所有日期聚合到一行。
  • 若日期類型為 NUMBER,直接比較;若為 DATE,需用 EXTRACT(DAY FROM 日期)。
  • PIVOT 語法更簡潔,但需 Oracle 11g 以上版本。

擴展:動態列(未知日期範圍)

若日期範圍不固定,需用動態 SQL(PL/SQL 塊中拼接列名再 EXECUTE IMMEDIATE),或在應用層組裝。

總結

行轉列的核心是條件聚合。Oracle 中 DECODE 或 CASE WHEN 配合 SUM 是通用做法;新版本可用 PIVOT 簡化代碼。

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