Съдейки по изхода ви, изглежда, че сте дефинирали START_DATE като времева марка. Ако беше обикновена дата, Oracle щеше да може да се справи с имплицитното преобразуване. Но тъй като не е, вие трябва изрично да прехвърляте тези низове, за да бъдат дати.
SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss'
2 /
Session altered.
SQL>
SQL> select * from t23
2 where start_date between '15-JAN-10' and '17-JAN-10'
3 /
no rows selected
SQL> select * from t23
2 where start_date between to_date('15-JAN-10') and to_date('17-JAN-10')
3 /
WIDGET START_DATE
------------------------------ ----------------------
Small Widget 15-JAN-10 04.25.32.000
SQL>
Но все пак получаваме само един ред. Това е така, защото START_DATE има елемент за време. Ако не посочим компонента за време, Oracle го определя по подразбиране на полунощ. Това е добре за от страна на BETWEEN
но не и за до страна:
SQL> select * from t23
2 where start_date between to_date('15-JAN-10')
3 and to_date('17-JAN-10 23:59:59')
4 /
WIDGET START_DATE
------------------------------ ----------------------
Small Widget 15-JAN-10 04.25.32.000
Product 1 17-JAN-10 04.31.32.000
SQL>
редактиране
Ако не можете да прехвърлите времевия компонент, има няколко възможности за избор. Едната е да промените клаузата WHERE, за да премахнете елемента време от критериите:
where trunc(start_date) between to_date('15-JAN-10')
and to_date('17-JAN-10')
Това може да окаже влияние върху производителността, защото дисквалифицира всеки индекс на b-дърво на START_DATE. Вместо това ще трябва да изградите индекс, базиран на функции.
Като алтернатива можете да добавите елемента за време към датата във вашия код:
where start_date between to_date('15-JAN-10')
and to_date('17-JAN-10') + (86399/86400)
Поради тези проблеми много хора предпочитат да избягват използването на between
като проверите за граници на датите като това:
where start_date >= to_date('15-JAN-10')
and start_date < to_date('18-JAN-10')