【问题标题】:BETWEEN Two Dates is Returning Rows of the Same Two Dates instead of the Ones BetweenBETWEEN Two Dates 返回相同两个日期的行,而不是返回之间的行
【发布时间】:2020-06-03 18:18:56
【问题描述】:

我正在尝试选择两个特定日期之间的行,但我得到的是与BETWEEN 中指定的相同日期的行。我尝试使用运算符 > 和

SELECT  r.RESERVATION_ID, a.AGENT_ID, a.AGENT_FNAME AS AGENT_NAME, t.TRIP_ID,
s.RESERVATION_STATUS

FROM RESERVATION r 
INNER JOIN AGENT a
ON
a.AGENT_ID=r.AGENT_ID

INNER JOIN TOURTRIP_RESERVATION t
ON
r.RESERVATION_ID=t.RESERVATION_ID

INNER JOIN RESERVATION_STATUS s
ON
r.RESERVATION_STATUSID=s.RESERVATION_STATUSID

WHERE r.AGENT_ID IS NOT NULL
AND r.RESERVATION_DATE BETWEEN '15-MAR-20' AND '26-MAY-20'
AND r.RESERVATION_STATUSID=100;

我使用to_date('03.06.2020','DD.MM.YYYY') 格式更新reservation_id 列中的数据。但是,当我使用

and RESERVATION_DATE > to_date('15.03.2020','DD.MM.YYYY') 
and RESERVATION_DATE < to_date('26.05.2020','DD.MM.YYYY')

它什么也没返回

这是预订表

【问题讨论】:

  • 您的 RESERVATION_DATE 列是日期数据类型吗?
  • 确实如此。这就是我添加日期的方式 TO_DATE('26-MAY-20')
  • 你好,你能告诉我们这个查询的结果是什么吗,SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_DATE_FORMAT'
  • 您好,谢谢您的建议。明天我会回复你,因为服务器已经关闭了一天。干杯
  • 如果有帮助,日期文字可以这样写:docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/…

标签: sql oracle select between


【解决方案1】:

介于的条件包括开始和结束。
您可以使用运算符 > 和
您的示例简化了:

create table RESERVATION (
 RESERVATION_ID number
,RESERVATION_DATE date)

数据:

insert into RESERVATION values (1, to_date('01.06.2020','DD.MM.YYYY'));
insert into RESERVATION values (2, to_date('02.06.2020','DD.MM.YYYY'));
insert into RESERVATION values (3, to_date('03.06.2020','DD.MM.YYYY'));

查询 A)

select RESERVATION_ID 
  from RESERVATION
 where RESERVATION_DATE between to_date('01.06.2020','DD.MM.YYYY') 
                            and to_date('03.06.2020','DD.MM.YYYY')

将返回:

1
2
3

查询 B)

select RESERVATION_ID 
  from RESERVATION
 where RESERVATION_DATE > to_date('01.06.2020','DD.MM.YYYY') 
   and RESERVATION_DATE < to_date('03.06.2020','DD.MM.YYYY')

会回来

2

我假设 RESERVATION_DATE 是一个日期。始终使用显式数据类型转换。

【讨论】:

    【解决方案2】:

    我更改了日期格式,试试这个,如果有其他结果,请告诉我。

    SELECT  r.RESERVATION_ID, a.AGENT_ID, a.AGENT_FNAME AS AGENT_NAME, t.TRIP_ID,
    s.RESERVATION_STATUS
    
    FROM RESERVATION r 
    INNER JOIN AGENT a
    ON
    a.AGENT_ID=r.AGENT_ID
    
    INNER JOIN TOURTRIP_RESERVATION t
    ON
    r.RESERVATION_ID=t.RESERVATION_ID
    
    INNER JOIN RESERVATION_STATUS s
    ON
    r.RESERVATION_STATUSID=s.RESERVATION_STATUSID
    
    WHERE r.AGENT_ID IS NOT NULL
    AND r.RESERVATION_DATE BETWEEN '2020-03-15' AND '2020-05-26'
    AND r.RESERVATION_STATUSID=100;
    

    【讨论】:

    • 我收到 ORA-01861:文字与格式字符串不匹配。这是否意味着我必须将表中的日期格式更新为查询的格式?
    • 是的,您需要像我的查询一样更改列的日期格式,
    【解决方案3】:

    如果RESERVATION_DATE 列的数据类型是DATE,请不要将其与字符串进行比较,因为'15-MAR-20' 是字符串。 Oracle 将尝试将其隐式转换为有效的日期值;有时它会成功,有时它会返回 false 值(因为它的 NLS 设置与您提供的不同),有时它会失败并引发错误。

    这两个:

    • date '2020-03-15'
    • to_date('15.03.2020', 'dd.mm.yyyy')

    另一方面,是日期

    BETWEENinclusive 并且将返回两个限制(如果它们存在):

    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_DATEVARCHAR2 列,那么您就大错特错了。永远不要将日期存储为字符串。如果您不能修改数据类型,则必须将其转换为日期:

    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>
    

    【讨论】:

    • 好的。我将使用新的日期格式更新表格,因为我使用 TO_DATE('26-MAY-20') 填充了 reservation_date 列并再次尝试查询
    • 正如我所说:这还不够。重新阅读我答案的最后一部分。
    • 我已经用更新和结果编辑了问题
    • 我根据您的示例数据添加示例来编辑答案。请看一下。
    • 我遵循了确切的步骤,但没有任何改变。我在会话之前和之后运行了“SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_DATE_FORMAT'',它仍然是 DD-MON-RR。 RR和YY是一回事吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 2020-09-15
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多