Vấn đề
Cột VARCHAR lưu ngày '21/10/2018' (DD/MM/YYYY). Cần truy vấn so sánh ngày (ví dụ: sau '2010-01-31').
Giải pháp: STR_TO_DATE trong WHERE
SELECT * FROM DemoTable WHERE STR_TO_DATE(DueDate, '%d/%m/%Y') > '2010-01-31';
Ví dụ minh họa
Tạo bảng và chèn dữ liệu
mysql> CREATE TABLE DemoTable (DueDate VARCHAR(100));
mysql> INSERT INTO DemoTable VALUES
('21/10/2018'), ('18/08/2019'), ('01/12/2012'), ('31/01/2016');
Truy vấn lọc ngày > 2010-01-31
mysql> SELECT * FROM DemoTable WHERE STR_TO_DATE(DueDate, '%d/%m/%Y') > '2010-01-31';
Kết quả (tất cả đều > 2010)
+------------+ | DueDate | +------------+ | 21/10/2018 | | 18/08/2019 | | 01/12/2012 | | 31/01/2016 | +------------+
Giải thích
STR_TO_DATE(DueDate, '%d/%m/%Y'): Chuyển chuỗi '21/10/2018' → DATE '2018-10-21'.- So sánh DATE với DATE literal '2010-01-31' → đúng logic.
⚠️ Hiệu năng
STR_TO_DATEchạy cho **mỗi dòng** → không dùng index trên cột DueDate.- Bảng lớn: Rất chậm (full table scan + CPU chuyển đổi).
Giải pháp tối ưu
- ALTER TABLE đổi kiểu cột sang DATE:
ALTER TABLE DemoTable MODIFY DueDate DATE;
(Cần UPDATE chuyển đổi dữ liệu trước). - Thêm cột ảo (Generated Column) MySQL 5.7+:
ALTER TABLE DemoTable ADD COLUMN DueDate_parsed DATE GENERATED ALWAYS AS (STR_TO_DATE(DueDate, '%d/%m/%Y')) STORED; CREATE INDEX idx_duedate_parsed ON DemoTable(DueDate_parsed);
- Tạo view: Che giấu logic chuyển đổi.