PostgreSQL 內建了幾個很方便的函式,讓你可以直接拿到目前的時間資訊。這些函式超適合用在像是自動記錄資料建立時間、根據今天日期產生報表、或是檢查某件事是不是在特定期間內發生的情境。來看看三個最常用的:NOW()、CURRENT_DATE 跟 CURRENT_TIME。
NOW():取得目前日期與時間
NOW() 這個函式會回傳目前的日期和時間,型別是 TIMESTAMP WITH TIME ZONE。也就是說,結果裡面會包含伺服器的時區資訊。
範例:
SELECT NOW();
-- 結果:2025-05-25 14:30:45.761523+03
注意,這個結果包含:
- 日期(
2025-05-25), - 時間(
14:30:45.761523), - 時區(
+03)。
如果你不想要時區,可以直接把結果轉成 TIMESTAMP:
SELECT NOW()::TIMESTAMP;
-- 結果:2025-05-25 14:30:45.761523
CURRENT_DATE:取得目前日期
CURRENT_DATE 這個函式只會回傳目前的日期,不會有時間。回傳型別是 DATE。
範例:
SELECT CURRENT_DATE;
-- 結果:2025-05-25
這個超適合用在你只在意日期、不在意時間的時候,比如算年齡、或是依照天數分組資料。
CURRENT_TIME:取得目前時間
CURRENT_TIME 這個函式會回傳目前的時間,型別是 TIME WITH TIME ZONE。如果你不需要時區,可以轉成 TIME。
範例:
SELECT CURRENT_TIME;
-- 結果:14:30:45.761523+03
SELECT CURRENT_TIME::TIME;
-- 結果:14:30:45.761523
函式的實用範例
來看幾個實際上會用到這些函式的例子。
自動填入資料建立時間
每次新增資料時,通常都會想自動記錄下建立的日期和時間。在 PostgreSQL 裡,你可以在建立資料表時設定 DEFAULT NOW() 來做到這件事。
建立資料表的範例:
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW() -- 建立這筆資料的時間
);
新增資料:
INSERT INTO orders (customer_name) VALUES ('Otto Lin');
來看一下資料表內容:
SELECT * FROM orders;
結果:
| id | customer_name | created_at |
|---|---|---|
| 1 | Otto Lin | 2024-11-25 14:45:12.154678 |
依日期篩選資料
假設你有一個訂單資料表,想要查詢今天建立的所有訂單。可以用 CURRENT_DATE 來做篩選:
SELECT *
FROM orders
WHERE created_at::DATE = CURRENT_DATE;
這裡我們用 created_at::DATE 來把時間去掉,只留下日期。
NOW() 跟 CURRENT_TIMESTAMP 的差異
乍看之下,NOW() 跟 CURRENT_TIMESTAMP 好像做一樣的事。其實真的差不多,只是 NOW() 跟 CURRENT_TIMESTAMP 分別來自不同的標準。
NOW() — PostgreSQL 的函式
NOW() 是 PostgreSQL 內建函式,回傳型別是 TIMESTAMP WITH TIME ZONE(timestamptz)。這是 SQL 查詢一開始時伺服器的時間。
範例:
SELECT NOW();
CURRENT_TIMESTAMP — SQL 標準
CURRENT_TIMESTAMP 是 SQL 標準 定義的語法,在 PostgreSQL 裡也會回傳 TIMESTAMP WITH TIME ZONE。其實 PostgreSQL 內部就是把 CURRENT_TIMESTAMP 當成跟 NOW() 一樣的東西來處理。
範例:
SELECT CURRENT_TIMESTAMP;
實際比較
SELECT NOW(), CURRENT_TIMESTAMP;
結果:
| now | current_timestamp |
|---|---|
| 2025-05-25 14:30:45+03 | 2025-05-25 14:30:45+03 |
兩個值會一模一樣,因為它們都是在 查詢一開始 就算出來的。
在條件篩選裡用時間函式
現在來寫個查詢,把最近 7 天內建立的資料都選出來。可以用 NOW() 搭配日期運算:
SELECT *
FROM orders
WHERE created_at >= NOW() - INTERVAL '7 days';
如果你想查詢本月的訂單,可以用 DATE_TRUNC() 這個函式來抓出這個月的第一天:
SELECT *
FROM orders
WHERE created_at >= DATE_TRUNC('month', NOW());
DATE_TRUNC() 這個函式還蠻酷的,之後幾堂課我會再多講一點 :P
實用小技巧
- 如果你需要精確的時間(包含時區),用
NOW()或CURRENT_TIMESTAMP。 - 只需要日期的話(像是算年齡、或分析某天的事件),就用
CURRENT_DATE。 CURRENT_TIME通常用在報表或介面上,想要顯示花了多少時間在某個任務上。
下一堂課我們會開始用 EXTRACT() 跟 AGE() 這些函式來拆解日期和時間。這樣你就可以很輕鬆地算出一個人的年齡,或是依照天、月、年來處理資料囉!
GO TO FULL VERSION