比较日期问题

zmk*_*mki 0 oracle

我创建了一个包含以下列的表:

CREATE TABLE INDICADOR_DADOS
(

  ID       VARCHAR2(10 CHAR)   NOT NULL,
  DATE_START       DATE        NOT NULL,
  DATA_END         DATE        NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)

现在需要在添加之前,检查是否有打算添加以下查询的日期:

 select COUNT(*) as count from indicador_dados
        where id='23' and TO_DATE(data_inicio,'yyyy/mm/dd') 
            between to_date('2013/05/15','yyyy/mm/dd')
            and to_date('2013/05/16','yyyy/mm/dd')
Run Code Online (Sandbox Code Playgroud)

问题是这个查询不是要返回 1,因为它们必须在数据库 05/03/2013 (date_start) 和 17/05/2013(date_end) 中。有人可以帮助我吗?

也许重复:oracle-datetime-in-where-clause但没有帮助我解决

Vin*_*rat 7

我发现您的日期过滤器存在两个问题:

  1. 您正在申请TO_DATE一种DATE数据类型。它不仅是多余的,而且实际上会导致意想不到的行为

    以下是 Oracle 分析表达式的方式TO_DATE(data_inicio,'yyyy/mm/dd')

    • Oracle 搜索名为TO_DATE具有两个参数 ( DATE, VARCHAR2)的函数
    • 由于不存在这样的函数,Oracle 会寻找可通过隐式转换访问的相关函数。
    • (Un)幸运的是,TO_DATE存在单个函数,所以这里没有歧义,选择的函数是TO_DATE(VARCHAR2, VARCHAR2)
    • 您的日期将转换为具有当前会话日期格式的 VARCHAR2 ,这意味着行为是不可预测的。该表达式等效于:

      TO_DATE(TO_CHAR(data_inicio, 'current NLS_DATE_FORMAT'), 'yyyy/mm/dd')
      
      Run Code Online (Sandbox Code Playgroud)

      在这种情况下,如果您NLS_DATE_FORMATYYYY/MM/DD.

    你永远不应该依赖隐式转换,因为行为是依赖于上下文的。

  2. 您的间隔过滤器是错误的:两个间隔,[A,B]并且[C,D]当且仅当:

    • A <= D
    • B >= C

您的查询应如下所示:

SELECT COUNT(*) AS COUNT
  FROM indicador_dados
 WHERE id = '23'
   AND date_start  <= to_date('2013/05/16', 'yyyy/mm/dd')
   AND date_end >= to_date('2013/05/15', 'yyyy/mm/dd')
Run Code Online (Sandbox Code Playgroud)