HỎI: Tại sao SQL bao gồm GIỮA?
TRẢ LỜI: Bởi vì các nhà thiết kế ngôn ngữ SQL đã đưa ra một quyết định thiết kế kém, trong đó họ không cung cấp cú pháp cho phép các nhà phát triển chỉ định biến thể nào trong 4 biến thể của GIỮA (đóng, bán mở trái, bán phải hoặc mở ) họ muốn.
KIẾN NGHỊ: Trừ khi / cho đến khi tiêu chuẩn SQL được sửa đổi, không sử dụng GIỮA cho ngày / lần. Thay vào đó, hãy tập thói quen mã hóa so sánh phạm vi DATE dưới dạng các điều kiện độc lập trên ranh giới bắt đầu và kết thúc của phạm vi GIỮA của bạn. Đây là một chút dài dòng, nhưng sẽ để lại cho bạn các điều kiện viết trực quan (do đó ít có lỗi hơn) và rõ ràng với các trình tối ưu hóa cơ sở dữ liệu, cho phép xác định các kế hoạch thực hiện tối ưu và sử dụng các chỉ mục.
Ví dụ: nếu truy vấn của bạn chấp nhận thông số kỹ thuật của ngày đầu vào và sẽ trả về tất cả các bản ghi rơi vào ngày đó, bạn sẽ mã là:
WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1
Cố gắng viết logic bằng cách sử dụng GIỮA rủi ro về các vấn đề về hiệu năng và / hoặc mã lỗi. Ba sai lầm phổ biến:
1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1
Đây gần như chắc chắn là một lỗi - người dùng hy vọng sẽ chỉ thấy các bản ghi cho một ngày cụ thể, nhưng một ngày nào đó sẽ xuất hiện với một báo cáo có chứa các bản ghi từ 12:00 sáng ngày hôm sau.
2) WHERE TRUNC(DATE_FIELD) = :dt
Đưa ra câu trả lời đúng, nhưng áp dụng chức năng cho DATE_FIELD sẽ khiến hầu hết việc lập chỉ mục / thống kê trở nên vô dụng (mặc dù đôi khi các DBA sẽ cố gắng giúp bằng cách thêm các chỉ mục dựa trên chức năng vào các trường ngày - vẫn đốt cháy thời gian của con người và không gian đĩa và thêm chi phí vào IUD thao tác trên bàn)
3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60
Tom Kyte, Oracle gord Extraordinaire, đề xuất giải pháp ít thanh lịch (IMO) này. Hoạt động tuyệt vời cho đến khi bạn dành cả ngày để thấy rằng "1-1 / 24/06/60" trong truy vấn mang lại kết quả không đầy đủ ... hoặc cho đến khi bạn vô tình sử dụng nó trên trường TIMESTAMP. Thêm vào đó, nó là một chút độc quyền; tương thích với kiểu dữ liệu DATE của Oracle (theo dõi thứ hai), nhưng cần được điều chỉnh theo độ chính xác DATE / TIME của các sản phẩm cơ sở dữ liệu khác nhau.
GIẢI PHÁP: Yêu cầu ủy ban SQL ANSI tăng cường các đặc tả ngôn ngữ SQL bằng cách sửa đổi cú pháp GIỮA để hỗ trợ đặc tả các lựa chọn thay thế cho mặc định ĐÓNG / INCLUSIVE. Một cái gì đó như thế này sẽ thực hiện các mẹo:
expr1 GIỮA expr2 [ INCL [USIVE] | EXCL [USIVE]] VÀ expr3 [ INCL [USIVE] | EXCL [USIVE]]
Xem xét cách dễ dàng để thể hiện WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(hoặc chỉ WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)
Có lẽ ANSI SQL: 2015?