CodeGym /Các khóa học /SQL SELF /Trích xuất phần của ngày: EXTRACT() và AGE()

Trích xuất phần của ngày: EXTRACT() và AGE()

SQL SELF
Mức độ, Bài học
Có sẵn

Hôm nay tụi mình lại đào sâu vào việc thao tác dữ liệu thời gian, học cách lấy ra các phần cụ thể (ví dụ như năm, tháng hoặc thứ trong tuần) bằng hàm EXTRACT() và tìm hiểu cách tính tuổi hoặc khoảng thời gian giữa hai ngày với hàm AGE().

Làm việc với dữ liệu thời gian trong các dự án thực tế thường cần phải tách lấy các phần cụ thể của ngày hoặc giờ. Ví dụ:

  • Phân chia đơn hàng theo năm hoặc tháng;
  • Đếm số lượng người dùng đăng ký vào một ngày cụ thể trong tuần;
  • Phân tích độ dài thời gian giữa hai sự kiện.

Để giải quyết mấy bài toán này, tụi mình dùng các hàm EXTRACT() và AGE().

EXTRACT() là gì?

Hàm EXTRACT() cho phép lấy ra các phần cụ thể của ngày hoặc timestamp. Ví dụ, bạn có thể lấy năm từ ngày sinh, xác định số tháng hoặc thậm chí lấy thứ trong tuần.

Cú pháp:

EXTRACT(part FROM source)
  • part: phần của ngày mà bạn muốn lấy. Có thể là YEAR, MONTH, DAY, HOUR, MINUTE, SECOND và các loại khác.
  • source: kiểu dữ liệu thời gian mà bạn muốn lấy thông tin. Có thể là cột, hằng số hoặc kết quả của một hàm.

Ví dụ 1: lấy năm, tháng và ngày

SELECT
    EXTRACT(YEAR FROM '2024-11-15'::DATE) AS year_part,
    EXTRACT(MONTH FROM '2024-11-15'::DATE) AS month_part,
    EXTRACT(DAY FROM '2024-11-15'::DATE) AS day_part;

Kết quả:

year_part month_part day_part
2024 11 15

Ở đây tụi mình đã lấy ra năm, tháng và ngày từ ngày 2024-11-15. Cách này rất hữu ích khi cần group dữ liệu theo từng phần của ngày.

Ví dụ 2: thứ trong tuần và giờ từ thời gian

SELECT
    EXTRACT(DOW FROM '2024-11-15'::DATE) AS day_of_week,
    EXTRACT(HOUR FROM '15:30:00'::TIME) AS hour_part;

Kết quả:

day_of_week hour_part
3 15
  • DOW (Day of Week) trả về số thứ trong tuần: chủ nhật — 0, thứ hai — 1, v.v.
  • HOUR lấy ra giờ từ thời gian.

Ví dụ 3: áp dụng cho cột

Nếu tụi mình có một bảng chứa các ngày, có thể lấy từng phần của ngày để phân tích. Giả sử có bảng orders:

order_id order_date
1 2023-05-12 14:20
2 2023-06-18 10:45
3 2023-07-22 21:15
SELECT
    order_id,
    EXTRACT(MONTH FROM order_date) AS month,
    EXTRACT(DAY FROM order_date) AS day
FROM orders;

Kết quả:

order_id month day
1 5 12
2 6 18
3 7 22

AGE() là gì?

Hàm AGE() dùng để tính khoảng cách giữa hai timestamp. Ví dụ, nó giúp tính tuổi khách hàng dựa trên ngày sinh hoặc xác định đã bao lâu kể từ khi đặt hàng.

Cú pháp:

AGE(timestamp1, timestamp2)
  • timestamp1: timestamp muộn hơn.
  • timestamp2: timestamp sớm hơn.
  • Nếu chỉ truyền một tham số, PostgreSQL sẽ tự động so sánh với ngày hiện tại (NOW()).

Ví dụ 1: tính tuổi

SELECT AGE('2025-11-15'::DATE, '1990-05-12'::DATE) AS age;

Kết quả:

age
35 years 6 mons

Ví dụ này cho thấy tuổi của một người sinh ngày 12 tháng 5 năm 1990 tính đến ngày 15 tháng 11 năm 2025.

Ví dụ 2: khoảng thời gian giữa các sự kiện

SELECT AGE('2023-06-01 15:00'::TIMESTAMP, '2023-05-20 10:30'::TIMESTAMP) AS duration;

Kết quả:

duration
11 days 4:30:00

Ở đây tụi mình tính khoảng thời gian giữa hai sự kiện. Rất hữu ích khi cần biết đã bao lâu từ lúc bắt đầu đến khi hoàn thành một task.

Ví dụ 3: tuổi của khách hàng

Giả sử có bảng customers:

customer_id birth_date
1 1992-03-10
2 1985-07-07

Tụi mình có thể tính tuổi khách hàng như sau:

SELECT
    customer_id,
    AGE(NOW(), birth_date) AS age
FROM customers;

Kết quả vào ngày 13 tháng 6 năm 2025:

customer_id age
1 33 years 3 mons
2 39 years 11 mons

Dĩ nhiên, bạn sẽ có giá trị NOW() và kết quả riêng của mình.

Ví dụ thực tế dùng EXTRACT() và AGE()

Giờ tụi mình kết hợp các hàm này trong các tình huống thực tế nhé.

Ví dụ 1: group dữ liệu theo tháng

Giả sử có bảng đơn hàng với ngày đặt. Để đếm số đơn theo từng tháng, dùng câu lệnh sau:

SELECT
    EXTRACT(MONTH FROM order_date) AS order_month,
    COUNT(*) AS total_orders
FROM orders
GROUP BY order_month
ORDER BY order_month;

Ví dụ 2: số ngày còn lại đến hạn

Giả sử có bảng subscriptions:

subscription_id expiry_date
1 2023-12-31
2 2024-05-15

Tụi mình muốn biết còn bao nhiêu ngày đến khi hết hạn:

SELECT
    subscription_id,
    AGE(expiry_date, NOW()) AS time_remaining
FROM subscriptions;

Kết quả:

subscription_id time_remaining
1 1 mons 15 days
2 6 mons

Lỗi thường gặp và cách tránh

Khi dùng EXTRACT() và AGE(), mấy bạn mới hay gặp mấy lỗi sau:

  • Cố lấy phần không hợp lệ, ví dụ lấy tháng từ kiểu TIME. Nhớ nha: các phần YEAR, MONTH và DAY chỉ dùng với DATE, TIMESTAMP, không dùng với TIME.
  • Vấn đề với các định dạng thời gian khác nhau. Ví dụ, chuỗi 2023/11/15 không được coi là ngày. Hãy dùng ép kiểu với ::DATE hoặc TO_DATE().
  • Khác biệt giữa AGE() và phép trừ timestamp. Nếu bạn cần khoảng thời gian chính xác (tháng, ngày, giây) — dùng AGE(), còn nếu chỉ cần số ngày thì dùng phép toán trừ bình thường.

Giờ thì bạn đã có đủ skill để lấy và phân tích các phần của dữ liệu thời gian trong PostgreSQL rồi đó. Thử nghịch với EXTRACT() và AGE() trong project của bạn đi nhé!

2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Tính tuổi của khách hàng tại ngày hiện tại
Tính tuổi của khách hàng tại ngày hiện tại
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION