ВОПРОС: Почему SQL между включительно?
ОТВЕТ: Поскольку разработчики языка SQL приняли плохое проектное решение, им не удалось предоставить синтаксис, который позволил бы разработчикам указать, какой из 4 вариантов BETWEEN (закрытый, полуоткрытый левый, полуоткрытый правый или открытый они бы предпочли.
РЕКОМЕНДАЦИЯ: Если / до тех пор, пока не будет изменен стандарт SQL, не используйте МЕЖДУ для дат / времени. Вместо этого приобретите привычку кодировать сравнения диапазона ДАТЫ как независимые условия на начальной и конечной границах вашего диапазона МЕЖДУ. Это немного многословно, но оставит вам написание условий, которые являются интуитивно понятными (а значит, менее подвержены ошибкам) и понятными оптимизаторам базы данных, что позволяет определять оптимальные планы выполнения и использовать индексы.
Например, если ваш запрос принимает спецификацию входного дня и должен вернуть все записи, приходящиеся на эту дату, вы должны кодировать как:
WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1
Попытка написать логику с помощью BETWEEN рискует проблемами с производительностью и / или ошибочным кодом. Три распространенных оплошности:
1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1
Это почти наверняка ошибка - пользователь ожидает увидеть только записи за определенную дату, но в один прекрасный день будет получен отчет, содержащий записи с 12:00 следующего дня.
2) WHERE TRUNC(DATE_FIELD) = :dt
Дает правильный ответ, но применение функции к DATE_FIELD сделает большую часть индексации / статистики бесполезной (хотя иногда администраторы баз данных пытаются помочь, добавляя индексы на основе функций к полям даты - по-прежнему сжигая человеко-часы и дисковое пространство и добавляя накладные расходы на IUD операции на столе)
3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60
Том Кайт, экстраординарный гуру Oracle, рекомендует это не слишком элегантное (IMO) решение. Работает отлично, пока вы не потратите весь день на поиск этого «1-1 / 24/06/60» в запросе, который дает неполные результаты ... или пока вы случайно не используете его в поле TIMESTAMP. Плюс, это немного запатентовано; совместим с типом данных Oracle DATE (который отслеживает второй), но должен быть скорректирован с точностью DATE / TIME различных продуктов баз данных.
РЕШЕНИЕ: обратиться в комитет ANSI SQL с просьбой улучшить спецификации языка SQL, изменив синтаксис BETWEEN для поддержки спецификации альтернатив по умолчанию CLOSED / INCLUSIVE. Нечто подобное могло бы сработать:
выражение1 МЕЖДУ expr2 [ ВКЛ [USIVE] | EXCL [USIVE]] И expr3 [ ВКЛ [USIVE] | EXCL [USIVE]]
Подумайте, как легко выразить WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE
(или просто WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL
)
Может быть, ANSI SQL: 2015?