ЗАПИТАННЯ: Чому SQL в МІЖ включено?
ВІДПОВІДЬ: Оскільки дизайнери мови SQL прийняли неякісне дизайнерське рішення, оскільки вони не змогли надати синтаксис, який дозволить розробникам вказати, який із 4 варіантів BETWEEN (закритий, напіввідкритий-лівий, напіввідкритий-правий чи відкритий ) вони вважають за краще.
РЕКОМЕНДАЦІЯ: Якщо / до внесення змін до стандарту SQL, не використовуйте МЕЖДУ для дати / часу. Натомість увійдіть у звичку кодувати порівняння діапазону DATE як незалежні умови на початковій та кінці меж діапазону BETWEEN. Це трохи детально, але це дозволить вам створити інтуїтивно зрозумілі умови (таким чином менше шансів на помилку) та зрозумілі для оптимізаторів бази даних, що дозволить визначити оптимальні плани виконання та використовувати індекси.
Наприклад, якщо ваш запит приймає специфікацію дня введення і повинен повертати всі записи, які потрапили на цю дату, ви кодуєте:
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 зробить більшу частину індексації / статистикою марною (хоча іноді DBA намагатимуться допомогти, додавши індекси, засновані на функціях, до полів дати - все ще спалюючи людино-години та дисковий простір та додаючи накладні витрати на IUD операції на столі)
3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60
Том Кіт, додатковий колектив гуру Oracle, рекомендує це не менш елегантне рішення (IMO). Працює чудово, поки ви не витрачаєте цілий день, щоб знайти той "1-1 / 24/06/60" у запиті, який дає неповні результати ... або поки ви випадково не використаєте його в полі TIMESTAMP. Плюс, це трохи фірмові; сумісний з типом даних DATE від Oracle (який відстежує до другого), але його потрібно пристосувати до точності DATE / TIME для різних продуктів бази даних.
РЕШЕННЯ: Запросити комітет ANSI SQL для покращення специфікацій мови SQL, змінивши синтаксис BETWEEN для підтримки специфікації альтернатив за замовчуванням CLOSED / INCLUSIVE. Щось подібне зробило б трюк:
вираження1 МІЖ expr2 [ ВКЛ [USIVE] | EXCL [USIVE]] І expr3 [ INCL [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?