เมื่อต้องการหาวันที่ที่ใกล้ที่สุดในอนาคต (Next Closest Date) จากชุดวันที่ในตาราง โดยเปรียบเทียบกับวันที่/เวลาปัจจุบัน สามารถใช้ ORDER BY แบบเฉพาะเจาะจงพร้อม LIMIT 1
ตัวอย่างการใช้งาน
สร้างตารางวันที่จัดส่ง:
mysql> CREATE TABLE DemoTable1454 (ShippingDate DATE);
เพิ่มข้อมูล (มีทั้งอดีตและอนาคต):
mysql> INSERT INTO DemoTable1454 VALUES ('2019-10-01'), ('2019-10-03'), ('2019-10-05'), ('2019-10-04'), ('2018-10-06'), ('2019-10-06');
ดูข้อมูลและวันที่ปัจจุบัน:
mysql> SELECT * FROM DemoTable1454; +--------------+ | ShippingDate | +--------------+ | 2019-10-01 | | 2019-10-03 | | 2019-10-05 | | 2019-10-04 | | 2018-10-06 | | 2019-10-06 | +--------------+ mysql> SELECT NOW(); +---------------------+ | now() | +---------------------+ | 2019-10-04 21:30:01 | +---------------------+
หาวันที่จัดส่งถัดไปที่ใกล้ที่สุด (หลังจาก NOW()):
mysql> SELECT * FROM DemoTable1454
-> ORDER BY (ShippingDate > NOW()) DESC,
-> (CASE WHEN ShippingDate > NOW() THEN ShippingDate END),
-> ShippingDate DESC
-> LIMIT 1;
ผลลัพธ์ (2019-10-05 คือวันที่ถัดไปหลัง 2019-10-04):
+--------------+ | ShippingDate | +--------------+ | 2019-10-05 | +--------------+
คำอธิบาย Logic การเรียง (ORDER BY)
(ShippingDate > NOW()) DESC: ใส่วันที่ในอนาคต (TRUE=1) ไว้หน้า, อดีต (FALSE=0) ไว้ท้ายCASE WHEN ShippingDate > NOW() THEN ShippingDate END: เรียงวันที่ในอนาคตจากน้อยไปมาก (ASC implicit)ShippingDate DESC: Tie-breaker สำหรับวันที่ในอดีต (ไม่สำคัญเพราะ LIMIT 1)
วิธีง่ายกว่า (MySQL 8.0+ / MariaDB)
-- ใช้ WHERE กรองเฉพาะอนาคต แล้ว ORDER BY ASC LIMIT 1 SELECT * FROM DemoTable1454 WHERE ShippingDate > NOW() ORDER BY ShippingDate ASC LIMIT 1;
วิธีนี้อ่านง่ายกว่า ใช้ Index ได้ และประสิทธิภาพดีกว่า
กรณีต้องการ "วันที่ใกล้ที่สุด" ทั้งอดีตและอนาคต (Nearest Date)
SELECT * FROM DemoTable1454 ORDER BY ABS(DATEDIFF(ShippingDate, NOW())) LIMIT 1;
ใช้ ABS(DATEDIFF(...)) หาความต่างวันแบบสัมบูรณ์ แล้วเรียงน้อยไปมาก