Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Thực hiện SELECT trên ngày lưu dạng VARCHAR trong MySQL với STR_TO_DATE


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_DATE chạ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

  1. 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).
  2. 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);
  3. Tạo view: Che giấu logic chuyển đổi.