การแปลง VARCHAR เป็น DATE เพื่อเปรียบเทียบกับ CURDATE()
เมื่อวันที่เก็บเป็น VARCHAR (เช่น '01/04/2019') ต้องแปลงเป็น DATE ด้วย STR_TO_DATE() ก่อนจึงจะเปรียบเทียบกับ CURDATE() ได้ถูกต้อง
สร้างตารางและข้อมูล
mysql> create table DemoTable1397 (
-> AdmissionDate varchar(40)
-> );
Query OK, 0 rows affected (0.97 sec)
mysql> insert into DemoTable1397 values('01/04/2019');
mysql> insert into DemoTable1397 values('27/09/2019');
mysql> insert into DemoTable1397 values('29/09/2018');
mysql> insert into DemoTable1397 values('29/09/2019');
ข้อมูลและวันที่ปัจจุบัน
mysql> select * from DemoTable1397; +---------------+ | AdmissionDate | +---------------+ | 01/04/2019 | | 27/09/2019 | | 29/09/2018 | | 29/09/2019 | +---------------+ mysql> select curdate(); +------------+ | curdate() | +------------+ | 2019-09-27 | +------------+
คำสั่งเปรียบเทียบ (วันที่มากกว่าวันนี้)
mysql> select * from DemoTable1397
-> where str_to_date(AdmissionDate, '%d/%m/%Y') > curdate();
ผลลัพธ์
+---------------+ | AdmissionDate | +---------------+ | 29/09/2019 | +---------------+
Format Specifiers สำหรับ STR_TO_DATE
| Specifier | ความหมาย | ตัวอย่าง |
|---|---|---|
%d | วัน (01-31) | 01, 27, 29 |
%m | เดือน (01-12) | 04, 09 |
%Y | ปี 4 หลัก | 2019 |
%y | ปี 2 หลัก | 19 |
%H | ชั่วโมง 24h (00-23) | 14 |
%i | นาที (00-59) | 30 |
%s | วินาที (00-59) | 45 |
รูปแบบวันที่พบบ่อย
'%d/%m/%Y'— 29/09/2019 (ไทย, ยุโรป)'%m/%d/%Y'— 09/29/2019 (US)'%Y-%m-%d'— 2019-09-29 (ISO, MySQL native)'%d-%b-%Y'— 29-Sep-2019
ประสิทธิภาพและ Index
STR_TO_DATE() ใน WHERE clause ทำให้ index บนคอลัมน์ VARCHAR ไม่ได้ใช้งาน (non-sargable)
แนวทางแก้:
- เปลี่ยนคอลัมน์เป็น
DATEหรือDATETIMEtype (Best) - เพิ่ม Generated Column (MySQL 5.7+):
AdmissionDateParsed DATE GENERATED ALWAYS AS (STR_TO_DATE(AdmissionDate, '%d/%m/%Y')) STOREDแล้ว index คอลัมน์นี้ - แปลงข้อมูลครั้งเดียว (ETL) แล้วเก็บเป็น DATE