Báo cáo tháng 1 thiếu 4% doanh thu. Không ai tìm ra trong sáu tháng. Thủ phạm là chữ BETWEEN.
Bài toán
Lấy toàn bộ đơn hàng trong tháng 1. Câu ai cũng viết:
WHERE ngay_dat BETWEEN '2026-01-01' AND '2026-01-31';
Nếu ngay_dat có phần giờ, câu này chỉ lấy đến 00:00:00 ngày 31. Mọi đơn phát sinh trong ngày 31 đều biến mất.
Cách đúng: khoảng nửa mở
WHERE ngay_dat >= '2026-01-01'
AND ngay_dat < '2026-02-01';
Mẫu >= đầu AND < sau đúng với mọi kiểu dữ liệu, mọi múi giờ, và vẫn dùng được chỉ mục. Hãy biến nó thành phản xạ.
Lỗi thường gặp thứ hai: bọc hàm quanh cột
-- Chỉ mục bị bỏ qua, quét toàn bảng
WHERE YEAR(ngay_dat) = 2026 AND MONTH(ngay_dat) = 1
-- Chỉ mục được dùng
WHERE ngay_dat >= '2026-01-01' AND ngay_dat < '2026-02-01'
Quy tắc chung: vế trái luôn là cột trần. Mọi phép biến đổi đưa sang vế phải.
Các hàm cần thuộc
| Việc cần làm | PostgreSQL | MySQL |
|---|---|---|
| Ngày hôm nay | CURRENT_DATE | CURDATE() |
| Cộng 7 ngày | d + INTERVAL '7 day' | DATE_ADD(d, INTERVAL 7 DAY) |
| Số ngày giữa hai mốc | d2 - d1 | DATEDIFF(d2, d1) |
| Về đầu tháng | DATE_TRUNC('month', d) | DATE_FORMAT(d,'%Y-%m-01') |
| Lấy năm | EXTRACT(YEAR FROM d) | YEAR(d) |
Gom nhóm theo tháng cho đúng
-- SAI: gộp tháng 1 của mọi năm vào nhau
GROUP BY TO_CHAR(ngay_dat, 'Mon')
-- ĐÚNG
SELECT DATE_TRUNC('month', ngay_dat) AS thang, SUM(tong_tien)
FROM don_hang
GROUP BY 1
ORDER BY 1;
Gom nhóm và sắp xếp theo giá trị gốc, chỉ định dạng ở bước hiển thị cuối cùng.
Luyện tập
- LeetCode 197 — Rising Temperature (so sánh với ngày liền trước)
- LeetCode 1141 — User Activity for the Past 30 Days I
- LeetCode 1907 — Count Salary Categories
- LeetCode 1683 — Invalid Tweets
- HackerRank — SQL Project Planning
Tóm lại
- Không dùng
BETWEENcho cột có phần giờ. - Luôn dùng mẫu
>= đầu AND < sau. - Bọc hàm quanh cột là mất chỉ mục.
- Cú pháp ngày tháng khác nhau giữa các hệ quản trị — tra trước khi viết.
- Gom nhóm theo giá trị gốc, không gom theo chuỗi đã định dạng.
Bạn vừa học xong hàm ngày tháng
Sẵn sàng luyện tập chưa?
Làm bài tập hàm ngày tháng trên dữ liệu thật, chấm điểm ngay khi bạn bấm chạy.
Bắt đầu luyện tập →