從 DATE/TIMESTAMP 擷取年、月、日、時、分、秒等元件,Oracle 提供多種函數。本文比較 EXTRACT、TO_CHAR、SUBSTR(TO_CHAR(...)) 三種寫法的語法、效能、型別回傳差異,助您選擇最適合的方法。
| 目標 | EXTRACT (標準 SQL) | TO_CHAR (格式化) | SUBSTR + TO_CHAR (字串剖析) |
|---|---|---|---|
| 年份 | EXTRACT(YEAR FROM dt) | TO_CHAR(dt, 'YYYY') | SUBSTR(TO_CHAR(dt,'YYYY-MM-DD'),1,4) |
| 月份 | EXTRACT(MONTH FROM dt) | TO_CHAR(dt, 'MM') | SUBSTR(TO_CHAR(dt,'YYYY-MM-DD'),6,2) |
| 日期 | EXTRACT(DAY FROM dt) | TO_CHAR(dt, 'DD') | SUBSTR(TO_CHAR(dt,'YYYY-MM-DD'),9,2) |
| 時 (24h) | EXTRACT(HOUR FROM dt) (需 TIMESTAMP) | TO_CHAR(dt, 'HH24') | SUBSTR(TO_CHAR(dt,'HH24:MI:SS'),1,2) |
| 分 | EXTRACT(MINUTE FROM dt) | TO_CHAR(dt, 'MI') | SUBSTR(TO_CHAR(dt,'HH24:MI:SS'),4,2) |
| 秒 | EXTRACT(SECOND FROM dt) | TO_CHAR(dt, 'SS') | SUBSTR(TO_CHAR(dt,'HH24:MI:SS'),7,2) |
| 維度 | EXTRACT | TO_CHAR | SUBSTR+TO_CHAR |
|---|---|---|---|
| 回傳型別 | NUMBER(可直接運算、比較) | VARCHAR2(需轉型才能運算) | VARCHAR2 |
| 標準相容性 | ANSI SQL 標準,跨資料庫可攜 | Oracle 專屬格式模型 | 非標準,脆弱 |
| 效能 | 最佳(內部直接存取 datetime 結構) | 良好(格式化引擎優化) | 最差(雙重函數呼叫 + 字串操作) |
| NLS 敏感度 | 無(回傳數值) | 有(月份名稱、AM/PM 受 NLS_DATE_LANGUAGE 影響) | 高(依賴固定格式字串位置) |
| 適用資料型別 | DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL | DATE, TIMESTAMP | DATE, TIMESTAMP |
-- 1. 取得本月第一天 00:00:00 (數值運算友善)
SELECT TRUNC(SYSDATE, 'MM') FROM dual;
-- 2. 判斷某日期是否為當月
WHERE EXTRACT(MONTH FROM order_date) = EXTRACT(MONTH FROM SYSDATE)
AND EXTRACT(YEAR FROM order_date) = EXTRACT(YEAR FROM SYSDATE);
-- 3. 依月份分組統計 (數值 GROUP BY 效能優於字串)
SELECT EXTRACT(MONTH FROM created_dt) AS mth, COUNT(*)
FROM orders
GROUP BY EXTRACT(MONTH FROM created_dt)
ORDER BY mth;
-- 4. 顯示用途:TO_CHAR 格式化輸出
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS now_str FROM dual;
-- 5. 避免 SUBSTR 寫法(除非處理非標準字串來源)
-- BAD: SUBSTR(TO_CHAR(dt,'YYYY-MM-DD'),6,2) -- 格式一變即壞
EXTRACT,回傳 NUMBER、效能最佳、NLS 安全。TO_CHAR 指定明確格式模型。SUBSTR(TO_CHAR(...)) 擷取日期元件:脆弱、效能差、不可維護。TRUNC(dt, 'MM')、TRUNC(dt, 'YYYY')、LAST_DAY(dt)、ADD_MONTHS(dt, n) 等日期運算函數常比手工拼湊更簡潔。SELECT EXTRACT(DAY FROM (SYSTIMESTAMP - hire_date)) AS days_diff
FROM employees;
-- 也可用 NUMTODSINTERVAL / NUMTOYMINTERVAL 建構 INTERVAL 再 EXTRACT
掌握 EXTRACT 作為核心擷取工具,搭配 TO_CHAR 處理顯示,能寫出高效能、可攜帶、易維護的日期時間 SQL。