CodeGym /Các khóa học /SQL SELF /Làm tròn và cắt ngắn dữ liệu thời gian: DATE_TRUNC...

Làm tròn và cắt ngắn dữ liệu thời gian: DATE_TRUNC()

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

DATE_TRUNC() là một công cụ mạnh mẽ cho phép bạn cắt ngắn giá trị thời gian đến một đơn vị thời gian nhất định. Ví dụ, bạn có thể làm tròn timestamp đến đầu ngày, tháng, năm, giờ, v.v. Cái này cực kỳ hữu ích khi phân tích dữ liệu theo từng giai đoạn (kiểu như muốn nhóm đơn hàng theo ngày, tháng hoặc năm).

Hãy tưởng tượng ngày giờ giống như một chuỗi văn bản dài, nơi bạn có giờ, phút, giây. Hàm DATE_TRUNC() lấy chuỗi đó và "cắt" phần thừa, chỉ giữ lại phần bạn cần. Ví dụ:

  • Bạn muốn cắt ngày 2023-10-01 15:30:45 đến đầu ngày. Kết quả sẽ là 2023-10-01 00:00:00.
  • Hoặc bạn chỉ muốn giữ lại giây đầu tiên của giờ, tức là 2023-10-01 15:00:00.

Cú pháp

Cú pháp của hàm DATE_TRUNC() như sau:

DATE_TRUNC(field, source)
  • field — là đơn vị thời gian mà bạn muốn "cắt" ngày đến. Ví dụ, year, month, day, hour, minute.
  • source — là giá trị thời gian mà bạn muốn cắt ngắn. Nó có thể là một cột kiểu TIMESTAMP hoặc kết quả của một hàm khác, ví dụ NOW().

Ví dụ gọi đơn giản:

SELECT DATE_TRUNC('day', TIMESTAMP '2023-10-01 15:30:45');
-- Kết quả: 2023-10-01 00:00:00

Các trường được hỗ trợ

Dưới đây là danh sách một số đơn vị thời gian được hỗ trợ mà bạn có thể dùng với DATE_TRUNC():

Đơn vị thời gian Mô tả
year Đầu năm (ví dụ, 2023-01-01 00:00:00)
quarter Đầu quý (ví dụ, 2023-07-01 00:00:00)
month Đầu tháng (ví dụ, 2023-10-01 00:00:00)
week Đầu tuần* (ví dụ, 2023-09-25 00:00:00)
day Đầu ngày (ví dụ, 2023-10-01 00:00:00)
hour Đầu giờ (ví dụ, 2023-10-01 15:00:00)
minute Đầu phút (ví dụ, 2023-10-01 15:30:00)
second Đầu giây (ví dụ, 2023-10-01 15:30:45)

Đơn vị thời gian càng nhỏ thì kết quả cắt càng chính xác. À mà, tuần bắt đầu từ chủ nhật nhé :)

Ví dụ sử dụng DATE_TRUNC()

Cắt đến đầu ngày. Trong ví dụ này, mình sẽ lấy một timestamp và làm tròn nó đến đầu ngày:

SELECT DATE_TRUNC('day', TIMESTAMP '2023-10-01 15:30:45') AS truncated_day;
-- Kết quả: 2023-10-01 00:00:00

Cắt đến đầu tháng. Giờ mình sẽ cắt ngày đến đầu tháng:

SELECT DATE_TRUNC('month', TIMESTAMP '2023-10-01 15:30:45') AS truncated_month;
-- Kết quả: 2023-10-01 00:00:00

Cắt đến đầu năm. Thử làm tròn ngày đến đầu năm nhé:

SELECT DATE_TRUNC('year', TIMESTAMP '2023-10-01 15:30:45') AS truncated_year;
-- Kết quả: 2023-01-01 00:00:00

Dùng với thời gian hiện tại (NOW()). Nếu bạn muốn luôn làm việc với ngày giờ hiện tại, bạn có thể kết hợp DATE_TRUNC()NOW():

SELECT DATE_TRUNC('hour', NOW()) AS truncated_hour;
-- Kết quả sẽ phụ thuộc vào thời gian hiện tại, ví dụ: 2023-10-01 15:00:00

Nhóm đơn hàng theo tháng. Giờ đến ví dụ thực tế hơn. Giả sử bạn có một bảng đơn hàng, mỗi bản ghi có ngày đặt hàng. Bạn muốn đếm số đơn hàng mỗi tháng:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_date TIMESTAMP NOT NULL
);

INSERT INTO orders (order_date) VALUES
('2023-10-01 10:15:00'),
('2023-10-01 15:30:00'),
('2023-09-15 12:45:00'),
('2023-08-20 09:00:00'),
('2023-08-25 10:30:00');

SELECT DATE_TRUNC('month', order_date) AS order_month,
       COUNT(*) AS total_orders
FROM orders
GROUP BY order_month
ORDER BY order_month;

Kết quả:

order_month total_orders
2023-08-01 00:00 2
2023-09-01 00:00 1
2023-10-01 00:00 2

Các case thực tế khi dùng

Phân tích dữ liệu thời gian theo giai đoạn: muốn biết có bao nhiêu user đăng ký mỗi năm, tháng hay ngày? Dùng DATE_TRUNC() để nhóm dữ liệu nhé.

Làm báo cáo: làm tròn timestamp đúng cách sẽ giúp báo cáo dễ đọc hơn nhiều.

So sánh ngày giờ: nếu bạn có dữ liệu thời gian với độ chính xác cao (kiểu có cả mili giây), hãy cắt nó đến mức cần thiết để so sánh cho chuẩn.

Các lỗi thường gặp khi dùng DATE_TRUNC()

Dùng trường không được hỗ trợ. Ví dụ, trường millisecond không được hỗ trợ, nếu dùng sẽ bị lỗi liền.

Sai kiểu dữ liệu. Hàm DATE_TRUNC() chỉ hoạt động với các kiểu dữ liệu thời gian như TIMESTAMP. Nếu truyền vào chuỗi, bạn sẽ bị lỗi.

Lỗi làm tròn. Nhớ là DATE_TRUNC() luôn cắt thời gian đến đầu đơn vị thời gian chỉ định. Nếu bạn muốn làm tròn thời gian, nên dùng cách khác nhé.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION