練習時間一個半小時、上班一天 8 小時、休息 20 分鐘、煮蛋要 10 分鐘。這些都是時間區間的例子啦。
時間區間在實際應用裡超有用,比如你要算任務的截止時間、找出兩個日期的差距,或是加減時間。進入細節之前,先來回顧一下我們前面幾堂課講到哪裡。
在 PostgreSQL 裡,INTERVAL 是一種專門拿來表示一段時間的資料型別。跟其他時間型別不一樣,它不會記錄某個特定的日期或時間,而是描述一個期間,比如:「2 天」、「3 小時」、「5 分鐘」這種。
INTERVAL 的語法
你可以這樣寫時間區間:
INTERVAL '數字 時間單位'
範例:
INTERVAL '2 days' -- 兩天
INTERVAL '3 hours' -- 三小時
INTERVAL '15 minutes' -- 十五分鐘
INTERVAL '1 day 2 hours' -- 一天兩小時
PostgreSQL 支援很多種時間單位:year、month、day、hour、minute、second。你可以在同一個表達式裡混著用。
在查詢裡用 INTERVAL
INTERVAL 這個型別,跟其他時間型別(像 DATE、TIMESTAMP)一起用的時候特別強大。來看幾個常見操作。
把區間加到日期/時間上
你可以把時間區間加到日期或時間上。像這樣:
SELECT CURRENT_DATE + INTERVAL '7 days' AS delivery_date;
-- 算出 7 天後的日期
結果:
| delivery_date |
|---|
| 2023-10-08 |
從日期/時間減去區間
除了加,你也可以減時間區間:
SELECT NOW() - INTERVAL '2 hours' AS two_hours_ago;
-- 算出兩小時前的時間
結果:
| two_hours_ago |
|---|
| 2023-10-01 10:00:00.000 |
計算兩個日期的差距
INTERVAL 很強的功能之一,就是可以算兩個日期的差距:
SELECT '2023-10-15'::DATE - '2023-10-01'::DATE AS days_difference;
-- 算兩個日期之間有幾天
結果:
| days_difference |
|---|
| 14 days |
注意,這裡的結果也是一個時間區間喔。
INTERVAL 的實戰範例
計算送貨日期。 假設你有個網路商店,送貨時間是 3 到 7 天。你可以這樣算出可能的送貨日期:
SELECT CURRENT_DATE + INTERVAL '3 days' AS earliest_delivery,
CURRENT_DATE + INTERVAL '7 days' AS latest_delivery;
結果:
| earliest_delivery | latest_delivery |
|---|---|
| 2023-10-04 | 2023-10-08 |
計算任務完成時間。 假設有個 tasks 表,每個任務有開始時間,要算出加上持續時間後的結束時間:
CREATE TABLE tasks (
task_id SERIAL PRIMARY KEY,
task_name TEXT,
start_time TIMESTAMP,
duration INTERVAL
);
INSERT INTO tasks (task_name, start_time, duration)
VALUES
('準備報告', '2023-10-01 09:00:00', INTERVAL '4 hours'),
('測試應用程式', '2023-10-01 10:00:00', INTERVAL '2 hours 30 minutes');
SELECT task_name,
start_time,
start_time + duration AS end_time
FROM tasks;
結果:
| task_name | start_time | end_time |
|---|---|---|
| 準備報告 | 2023-10-01 09:00:00 | 2023-10-01 13:00:00 |
| 測試應用程式 | 2023-10-01 10:00:00 | 2023-10-01 12:30:00 |
比較任務所需時間。 有時你想找出所有花不到 3 小時就完成的任務:
SELECT task_name
FROM tasks
WHERE duration < INTERVAL '3 hours';
結果:
| task_name |
|---|
| 測試應用程式 |
INTERVAL 的實用小技巧
動態計算區間。 你可以把欄位裡的天數轉成區間來用:
SELECT CURRENT_DATE + (order_days || ' days')::INTERVAL AS order_due_date
FROM orders;
把區間轉成字串。 有時候你想把區間顯示成字串:
SELECT INTERVAL '2 days 3 hours'::TEXT AS interval_text;
結果:
| interval_text |
|---|
| 2 days 03:00:00 |
用 INTERVAL 常見的錯誤
雖然 INTERVAL 很強大,但用起來還是會遇到一些小雷。最常見的錯誤之一,就是格式寫錯。比如你寫 INTERVAL '2 hours and 30 minutes',這樣 PostgreSQL 會報錯,因為它不認得 "and"。正確寫法是:INTERVAL '2 hours 30 minutes'。
還有一個常見錯誤,就是忘記寫時間單位,像 INTERVAL '2'。PostgreSQL 會搞不懂這個「2」是什麼,所以記得一定要寫清楚單位(2 days、2 hours 這樣)。
GO TO FULL VERSION