คำถาม: ทำไมรวม SQL ระหว่าง?
คำตอบ: เนื่องจากนักออกแบบภาษา SQL ได้ทำการตัดสินใจการออกแบบที่ไม่ดีเนื่องจากพวกเขาไม่สามารถส่งไวยากรณ์ที่จะช่วยให้นักพัฒนาสามารถระบุว่าตัวแปร 4 ตัวใดของ BETWEEN (ปิด, กึ่งเปิดซ้าย, กึ่งเปิดขวาหรือเปิด ) พวกเขาต้องการ
คำแนะนำ: นอกจาก / จนกว่าจะมีการแก้ไขมาตรฐาน SQL อย่าใช้ระหว่างวันที่ / เวลา แทนที่จะเป็นนิสัยของการเข้ารหัสช่วงวันที่ DATE เป็นเงื่อนไขที่เป็นอิสระในขอบเขตเริ่มต้นและจุดสิ้นสุดของช่วง BETWEEN ของคุณ นี่เป็นคำอธิบายที่ละเอียด แต่จะทำให้คุณเขียนเงื่อนไขที่เข้าใจง่าย (มีโอกาสน้อยที่จะบั๊กกี้) และชัดเจนกับตัวปรับแต่งฐานข้อมูลเพื่อให้สามารถกำหนดแผนการดำเนินการที่เหมาะสมและใช้ดัชนีได้
ตัวอย่างเช่นหากแบบสอบถามของคุณยอมรับข้อกำหนดวันเข้าและควรส่งคืนระเบียนทั้งหมดที่อยู่ในวันนั้นคุณจะต้องรหัสเป็น:
WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1
พยายามเขียนตรรกะโดยใช้ระหว่างความเสี่ยงปัญหาประสิทธิภาพและ / หรือรหัสรถ สามนับครั้งไม่ถ้วนที่พบบ่อย:
1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1
นี่เป็นข้อผิดพลาดเกือบแน่นอน - ผู้ใช้คาดว่าจะเห็นเฉพาะระเบียนสำหรับวันที่ระบุ แต่วันหนึ่งจะสิ้นสุดลงด้วยรายงานที่มีบันทึกจากเวลา 12:00 น. ของวันถัดไป
2) WHERE TRUNC(DATE_FIELD) = :dt
ให้คำตอบที่ถูกต้อง แต่การใช้ฟังก์ชั่นกับ DATE_FIELD จะทำให้การจัดทำดัชนี / สถิติส่วนใหญ่ไร้ประโยชน์ (แม้ว่าบางครั้ง DBA จะพยายามช่วยด้วยการเพิ่มดัชนีตามฟังก์ชั่นในฟิลด์วันที่ - ยังคงเผาผลาญชั่วโมงมนุษย์ การดำเนินงานบนโต๊ะ)
3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60
Tom Kyte ผู้ชำนาญพิเศษด้าน Oracle guru แนะนำวิธีการแก้ปัญหาที่ไม่หรูหรา (IMO) นี้ ทำงานได้ดีจนกระทั่งคุณใช้เวลาทั้งวันเพื่อหาคำว่า "1-1 / 24/06/60" ในข้อความค้นหาที่ให้ผลลัพธ์ที่ไม่สมบูรณ์ ... หรือจนกว่าคุณจะใช้มันในฟิลด์ TIMESTAMP โดยไม่ตั้งใจ นอกจากนี้มันเป็นกรรมสิทธิ์เล็กน้อย เข้ากันได้กับประเภทข้อมูล DATE ของออราเคิล (ซึ่งติดตามไปที่สอง) แต่จำเป็นต้องปรับให้เข้ากับความแม่นยำ DATE / TIME ของผลิตภัณฑ์ฐานข้อมูลที่แตกต่างกัน
การแก้ไข: ร้องเรียนคณะกรรมการ ANSI SQL เพื่อปรับปรุงรายละเอียดภาษา SQL โดยการแก้ไขไวยากรณ์ระหว่างเพื่อรองรับคุณสมบัติของทางเลือกอื่น ๆ ที่เป็นค่าเริ่มต้น CLOSED / INCLUSIVE สิ่งนี้จะเป็นการหลอกลวง:
expr1ระหว่าง expr2 [ INCL [USIVE] | EXCL [ใช้งาน]] และexpr3 [ INCL [ใช้งาน] | EXCL [ใช้งาน]]
พิจารณาว่ามันง่ายที่จะแสดงWHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(หรือเพียงแค่WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)
อาจจะเป็น ANSI SQL: 2015?