ในการออกแบบระบบฐานข้อมูลที่ต้องจัดการกับมิติของเวลา เช่น ระบบจองห้องพัก, สัญญาจ้าง, แผนงานโครงการ หรือแคมเปญโปรโมชัน หนึ่งในเงื่อนไขที่พบบ่อยแต่สร้างความสับสนได้ง่ายที่สุดคือรูปแบบ
JavaScript
SELECT *
FROM projects
WHERE start_date >= '1982-08-05'
AND date_end <= '3000-12-31';
เงื่อนไขนี้ไม่ได้มีไว้สำหรับการค้นหาข้อมูลตามช่วงเวลาทั่วไป แต่มีเจตนาเฉพาะเจาะจงทางตรรกะ รวมถึงมีพฤติกรรมการทำงานบน Database Engine ที่นักพัฒนาจำเป็นต้องเข้าใจลึกซึ้ง
1. ทำไมถึงต้องใช้เงื่อนไขนี้? (The Core Intent)
เหตุผลเดียวในการใช้เงื่อนไขนี้คือ คุณต้องการข้อมูลที่มี “วงจรชีวิตทั้งหมดบรรจุอยู่ภายในกรอบเวลาอย่างสมบูรณ์” (Fully Contained / Enclosed)
หากกำหนดกรอบการค้นหาเป็นปี 1982 (1982-01-01 ถึง 1982-12-31):
- รายการที่เริ่มและจบในปี 1982
ดึงมาแสดง
- รายการที่เริ่มปี 1982 แต่ลากยาวมาจบปี 2003: ถูกตัดทิ้ง (เพราะ
start_date < '1982-01-01')
- รายการที่เริ่มปลายปี 1982 แต่ไปจบต้นปี 2007: ถูกตัดทิ้ง (เพราะ
date_end > '1982-12-31')
เคสการใช้งานจริงที่เหมาะสม
- โครงการประเภท Short-term
เช่น การตรวจสอบโปรเจกต์พิเศษที่ต้องเริ่มและส่งมอบภายในปีงบประมาณเดียวกันเท่านั้น
- สัญญาแบบปิด
2. จุดตัดสำคัญ: ระวังจำสับสนกับ “ช่วงเวลาคาบเกี่ยว” (Overlap)
ข้อผิดพลาดที่พบได้บ่อยที่สุดในโปรดักชัน คือ นักพัฒนาต้องการดึงงานที่ active ในช่วงเวลานั้น แต่กลับไปเขียนแบบ Contained
ถ้าโจทย์ธุรกิจคือ “อยากรู้ว่าในปี 1982 มีงานไหนบ้างที่กำลังดำเนินการอยู่” การใช้ start_date >= ... AND date_end <= ... จะทำให้ข้อมูลงานระยะยาว (เช่น งานที่เริ่มตั้งแต่ปี 1982 และจะเสร็จปี 2082) หายไปจากระบบทันที
สำหรับโจทย์ที่ต้องการดึงงานที่มีความคาบเกี่ยว (Overlap) ทั้งหมด สูตรที่ถูกต้องต้องเป็น
JavaScript
-- ดึงทุกงานที่มีชีวิตอยู่หรือคาบเกี่ยวในปี 1982
WHERE start_date <= '1982-12-31'
AND date_end >= '1982-01-01';