CodeGym /課程 /SQL SELF /日期和時間格式化: NOW()CURRENT_DATE...

日期和時間格式化: NOW()CURRENT_DATEDATE_PART()

SQL SELF
等級 5 , 課堂 2
開放

日期和時間不只是抽象的數字,而是資料裡超有價值的資訊關鍵!現實生活中你常常會遇到日期:像是按月份分析銷售、根據員工生日篩選,或是比較時間區間。會玩日期,查詢就能更靈活,分析也能更進階!

哪些情境下日期操作超重要:

  • 分析某個月的銷售數據。
  • 計算過去一年註冊的用戶數。
  • 依照時間區間產生報表(像是每月收入)。

PostgreSQL 有超多日期相關的函數,這裡我們先看最實用的幾個。

日期和時間的基本函數

函數 NOW() 會回傳資料庫伺服器的現在日期和時間。你想知道此刻的精確時間就用它。舉例:你要記錄新資料建立的時間。

語法:
SELECT NOW();

範例結果:

2023-11-05 15:23:45.123456+00

使用範例: 你想插入一筆訂單,記錄現在的日期和時間:

INSERT INTO orders (order_id, order_date, total_amount)
VALUES (1, NOW(), 150.00);
註解:這裡 NOW() 會自動把現在的日期和時間加到 order_date 欄位。

INSERT 的詳細玩法我們之後會講,敬請期待 :P

函數 CURRENT_DATE

如果你只想要日期,不要時間,就用 CURRENT_DATE。它只會回傳年、月、日。

語法:

SELECT CURRENT_DATE;

範例結果:

2023-11-05

使用範例: 假設你想查詢今天的訂單:

SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
註解:這裡我們把 order_date 欄位的日期和今天的日期做比較。

來點幽默:NOW() 就像你上班的咖啡,馬上現做現喝;CURRENT_DATE 就像牆上的月曆,只給你日期,沒有多餘細節。

DATE_PART() 抽取日期部分

DATE_PART() 這個函數可以讓你抽出日期的某個部分,像是年、月、日、時、分。舉例:你想算某一年的訂單數,或是找出星期幾。

語法:

DATE_PART('部分', 日期)

範例:

SELECT DATE_PART('year', NOW()) AS current_year;

範例結果:

current_year
2025

可以抽取的日期部分:

  • year:年。
  • month:月。
  • day:日。
  • hour:小時。
  • minute:分鐘。
  • second:秒。
  • dow:星期幾(0 = 星期日)。

範例 2:抽出現在日期的月份。

SELECT DATE_PART('month', CURRENT_DATE) AS current_month;

結果:

current_month
6

DATE_PART() 也能用來做進階運算。舉例:

你想選出今年出生的學生:

SELECT *
FROM students
WHERE DATE_PART('year', birth_date) = DATE_PART('year', CURRENT_DATE);

範例結果:

id first_name last_name birth_date grade
1 Otto Art 2025-03-12 9
2 Anna Pal 2025-07-08 8
3 Piu Wolf 2025-01-22 10
4 Eva Go 2025-09-30 7
5 Dan Sok 2025-06-14 9

實戰範例

有些範例會用到你還沒學過的語法,別擔心,很快你就能輕鬆搞定這些查詢啦!主要是想多給你看點真實案例,也順便賣個關子 :)

範例 1:計算用戶年齡

假設我們有一個 users 表,裡面有每個用戶的生日。我們想算出他們的年齡。

查詢:

SELECT user_id, first_name, last_name, 
       DATE_PART('year', CURRENT_DATE) - DATE_PART('year', birth_date) AS age
FROM users;

我們直接用現在的年份減掉生日的年份。這方法快,但不是最精確的年齡計算。

範例結果:

user_id first_name last_name age
101 Alex Lin 25
102 Maria Chi 30
103 Tor Coz 22
104 Nat Ive 27
105 Don Sok 35

範例 2:根據時間篩選

你想查詢過去一小時內的所有訂單:

SELECT *
FROM orders
WHERE order_date >= NOW() - INTERVAL '1 hour';

注意 INTERVAL(時間區間)用起來超方便!

範例 3:按月份分組

你想統計今年每個月的訂單數:

SELECT DATE_PART('month', order_date) AS order_month, COUNT(*) AS order_count
FROM orders
WHERE DATE_PART('year', order_date) = DATE_PART('year', CURRENT_DATE)
GROUP BY DATE_PART('month', order_date)
ORDER BY order_month;

這裡是用月份分組,然後按月份排序。

範例結果:

order_month order_count
1 120
2 95
3 134
4 110
5 42

範例 4:抽出星期幾

你想知道哪一天訂單最多:

SELECT DATE_PART('dow', order_date) AS day_of_week, COUNT(*) AS order_count
FROM orders
GROUP BY DATE_PART('dow', order_date)
ORDER BY order_count DESC;

DATE_PART('dow') 會回傳每筆訂單的星期幾(0 是星期日,1 是星期一,以此類推)。DOW 就是 DayOfWeek 的縮寫。

範例結果:

day_of_week order_count
5 210
4 190
3 175
2 160
1 140
6 120
0 95

注意常見錯誤

處理日期常常讓人頭痛,因為很容易出錯。這裡列幾個你可能會遇到的常見問題:

時間和日期格式:NOW() 或其他會回傳日期時間的函數時,一定要注意格式。像是你拿 order_dateCURRENT_DATE 比較時,要確定時間部分有被忽略或明確指定。

日期是字串格式: 很多資料庫會把日期存成字串(像是 text)。如果你直接用日期函數(像 DATE_PART()),就會出錯。記得資料型態要是 DATETIMESTAMP

時區不同: 如果你的伺服器和資料來源在不同時區,可能會搞混。建議用 TIMESTAMPTZ 處理時區。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION