Att döma av dina resultat ser det ut som att du har definierat START_DATE som en tidsstämpel. Om det vore ett vanligt datum skulle Oracle kunna hantera den implicita konverteringen. Men eftersom det inte är så behöver du uttryckligen göra dessa strängar till datum.
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>
Men vi får fortfarande bara en rad. Detta beror på att START_DATE har ett tidselement. Om vi inte anger tidskomponenten ställer Oracle den som standard till midnatt. Det är bra för från sidan av BETWEEN
men inte för tills sida:
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>
redigera
Om du inte klarar av tidsdelen finns det ett par val. En är att ändra WHERE-satsen för att ta bort tidselementet från kriterierna:
where trunc(start_date) between to_date('15-JAN-10')
and to_date('17-JAN-10')
Detta kan ha en inverkan på prestandan, eftersom det diskvalificerar alla b-trädindex START_DATE. Du skulle behöva bygga ett funktionsbaserat index istället.
Alternativt kan du lägga till tidselementet till datumet i din kod:
where start_date between to_date('15-JAN-10')
and to_date('17-JAN-10') + (86399/86400)
På grund av dessa problem föredrar många människor att undvika användningen av between
genom att leta efter datumgränser så här:
where start_date >= to_date('15-JAN-10')
and start_date < to_date('18-JAN-10')