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

Oracle 日期操作大全:30 種常用模式從基礎到工作日計算

     編輯:Oracle 資料庫基礎

一、 基礎擷取與格式化

需求SQL範例結果
季度TO_CHAR(sysdate,'Q')3
年TO_CHAR(sysdate,'YYYY')2024
月TO_CHAR(sysdate,'MM')08
日TO_CHAR(sysdate,'DD')15
星期幾 (數字 1-7)TO_CHAR(sysdate,'D')4
星期名稱TO_CHAR(sysdate,'DAY')THURSDAY
年中天數 (1-366)TO_CHAR(sysdate,'DDD')228
EXTRACT 年/月/日EXTRACT(YEAR FROM dt)標準 SQL,可用於 Partition Key

二、 相對日期快速計算

需求SQL
上個月最後一天LAST_DAY(ADD_MONTHS(sysdate,-1))
本月最後一秒TRUNC(ADD_MONTHS(sysdate,1),'MM') - 1/24/60/60
本週週一TRUNC(sysdate,'DAY') + 1
年初至今天數CEIL(sysdate - TRUNC(sysdate,'YEAR'))
今年第幾週TO_CHAR(sysdate,'FMWW')
本月第幾週TO_CHAR(sysdate,'WW') - TO_CHAR(TRUNC(sysdate,'MM'),'WW') + 1
本月天數TO_CHAR(LAST_DAY(sysdate),'DD')
今年天數ADD_MONTHS(TRUNC(sysdate,'YEAR'),12) - TRUNC(sysdate,'YEAR')
下個週一NEXT_DAY(sysdate,'MONDAY')
間隔 N 秒/分/時/天/月/年sysdate + N/24/60/60 / ADD_MONTHS(sysdate,N)
兩日期間天數FLOOR(sysdate - TO_DATE('20020405','YYYYMMDD'))

三、 進階計算:工作日 (排除週末)

建立測試資料


CREATE TABLE t (s DATE, e DATE);
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
INSERT INTO t VALUES ('2003-03-01','2003-03-03');
INSERT INTO t VALUES ('2003-03-02','2003-03-03');
INSERT INTO t VALUES ('2003-03-07','2003-03-08');  -- 週六~日
INSERT INTO t VALUES ('2003-03-07','2003-03-09');  -- 週六~一
INSERT INTO t VALUES ('2003-03-05','2003-03-07');  -- 週三~五
INSERT INTO t VALUES ('2003-02-01','2003-03-31');  -- 跨月
COMMIT;

核心邏輯:每天判斷是否週末,累加


SELECT s, e,
       (e - s + 1)                           AS total_days,
       (e - s + 1) -
       (TRUNC(e) - TRUNC(s) + 1) * 2/7       AS approx_workdays,  -- 粗估
       -- 精確:逐日展開判斷(需數字表或 CONNECT BY)
       (SELECT COUNT(*) FROM
         (SELECT TRUNC(s) + LEVEL - 1 dt FROM dual
          CONNECT BY LEVEL <= e - s + 1)
        WHERE TO_CHAR(dt,'DY','NLS_DATE_LANGUAGE=AMERICAN') NOT IN ('SAT','SUN')
       ) AS exact_workdays
FROM t;

**原理**:CONNECT BY LEVEL 產生日期序列 → TO_CHAR(dt,'DY') 判斷星期 → 排除 SAT/SUN。
**擴展**:加入假日表 holidays(dt) 進一步排除。

四、 判斷時段:上午/下午/晚上


SELECT CASE
         WHEN TO_NUMBER(TO_CHAR(sysdate,'HH24')) BETWEEN 6  AND 11 THEN '上午'
         WHEN TO_NUMBER(TO_CHAR(sysdate,'HH24')) BETWEEN 11 AND 17 THEN '下午'
         WHEN TO_NUMBER(TO_CHAR(sysdate,'HH24')) BETWEEN 17 AND 21 THEN '晚上'
         ELSE '深夜'
       END AS period
FROM dual;

五、 12c+ 標準語法:OFFSET / FETCH


SELECT * FROM emp ORDER BY hiredate
OFFSET 10 ROWS FETCH NEXT 20 ROWS ONLY;  -- 第 11-30 筆

取代傳統 ROWNUM 巢狀查詢,語意清晰、最佳化器支援完善。

六、 時區與 TIMESTAMP 進階

  • CURRENT_TIMESTAMP:Session 時區時間(含時區位移)。
  • SYSTIMESTAMP:資料庫伺服器 OS 時區時間。
  • FROM_TZ(TS, 'TZR'):附加時區資訊。
  • CAST(TS AS TIMESTAMP WITH LOCAL TIME ZONE):自動轉換至 Session 時區。

結語

Oracle 日期運算威力在於 **TRUNC/ROUND` 邊界對齊、`ADD_MONTHS` 月份邏輯、`INTERVAL` 語意運算、`CONNECT BY` 日期序列展開**。掌握上述 30 種模式,涵蓋 99% 業務場景。工作日計算以「日期序列 + 星期/假日過濾」為通用模板,靈活擴展。

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