如果RESERVATION_DATE 列的数据类型是DATE,请不要将其与字符串进行比较,因为'15-MAR-20' 是字符串。 Oracle 将尝试将其隐式转换为有效的日期值;有时它会成功,有时它会返回 false 值(因为它的 NLS 设置与您提供的不同),有时它会失败并引发错误。
这两个:
date '2020-03-15'
to_date('15.03.2020', 'dd.mm.yyyy')
另一方面,是日期。
BETWEEN 是inclusive 并且将返回两个限制(如果它们存在):
AND r.RESERVATION_DATE BETWEEN date '2020-03-15' and date '2020-05-26'
如果你想排除这些限制,那么
AND r.RESERVATION_DATE > date '2020-03-15'
AND r.RESERVATION_DATE < date '2020-05-26'
但是,如果 RESERVATION_DATE 是 VARCHAR2 列,那么您就大错特错了。永远不要将日期存储为字符串。如果您不能修改数据类型,则必须将其转换为日期:
and to_date(r.reservation_date, 'dd-mon-yy') between date '2020-03-15'
and date '2020-05-26'
只要该列中没有任何无效值,此将起作用。因为,因为它是一个字符串,所以您可以输入类似15-AA-2F 的内容,这当然不是日期,但可以存储在这样的列中。在这种情况下,查询将失败,您必须修复数据。
您发布的评论说您尝试了TO_DATE('26-MAY-20')。这还不够 - 您应该提供格式掩码,因为它可以是
- 2020 年 5 月 26 日
- 2026 年 5 月 20 日
这取决于 NLS 设置。此外,它会在我的数据库中失败:
因为 NLS 设置不同:
SQL> select to_date('26-may-20') from dual;
select to_date('26-may-20') from dual
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
因为我们在克罗地亚没有“可能”:
SQL> select to_date('26-may-20', 'dd-mon-yy') from dual;
select to_date('26-may-20', 'dd-mon-yy') from dual
*
ERROR at line 1:
ORA-01843: not a valid month
但这行得通,正如我告诉甲骨文我想要什么:
SQL> select to_date('26-may-20', 'dd-mon-yy', 'nls_date_language = english') from dual;
TO_DATE('26-MAY-20'
-------------------
26.05.2020 00:00:00
更好的是,仅使用数字或日期文字(始终为 date 'yyyy-mm-dd'):
SQL> select to_date('26.05.2020', 'dd.mm.yyyy') d1,
2 date '2020-05-26' d2
3 from dual;
D1 D2
------------------- -------------------
26.05.2020 00:00:00 26.05.2020 00:00:00
SQL>
根据您提供的示例数据,假设reservation_date 列的数据类型为date:
- 先设置环境
- 样本数据来自第 1 - 9 行
- 您需要的查询从第 10 行开始
给你:
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> alter session set nls_Date_format = 'dd-mon-yy';
Session altered.
SQL> with reservation (reservation_id, reservation_date, agent_id) as
2 (select 8576, date '2020-03-15', 222 from dual union all
3 select 7325, date '2020-05-26', 333 from dual union all
4 select 3186, date '2020-04-23', 111 from dual union all
5 select 8000, date '2020-04-05', 555 from dual union all
6 select 4120, date '2020-01-03', null from dual union all
7 select 1546, date '2020-02-15', null from dual union all
8 select 1007, date '2020-05-06', null from dual
9 )
10 select *
11 from reservation
12 where reservation_date between date '2020-03-15'
13 and date '2020-05-26'
14 order by reservation_date;
RESERVATION_ID RESERVATI AGENT_ID
-------------- --------- ----------
8576 15-mar-20 222
8000 05-apr-20 555
3186 23-apr-20 111
1007 06-may-20
7325 26-may-20 333
SQL>