查找两个日期之间的日期(最佳实践)

时间:2014-09-01 12:16:32

标签: sql oracle date

我有2个SQL脚本。一个像这样:

"Date" > '2014-04-11' AND "Date" <= '2014-04-12'

另一个像这样:

"Date" BETWEEN '2014-04-11' AND '2014-04-12'

现在我想知道是否有任何具体的最佳实践,一个理由做另一个,如果其中一个因某些明显的原因更好,我错过了某个地方。

2 个答案:

答案 0 :(得分:3)

您正在寻求最佳做法。我认为以下是最佳做法:

"Date" >= DATE '2014-04-11' AND "Date" < DATE '2014-04-12' + 1

首先,请注意使用DATE关键字。您的问题是关于日期,但您使用的是Oracle不直接支持的日期格式。令人高兴的是,Oracle支持ISO标准格式的DATE关键字。

其次,我添加了+1,以便您可以看到时间段的结束,这可能是您希望在代码中看到的内容。它不应该影响性能,因为+ 1是常量。

第三,日期常量具有时间分量。如果未指定,则为该日期的午夜。所以,表达式:

"Date" BETWEEN '2014-04-11' AND '2014-04-12'

真的:

"Date" >= TIMESTAMP '2014-04-11 00:00:00' AND "Date" <= TIMESTAMP '2014-04-12 00:00:00'

也就是说,包含了从晚些时候开始的一次,即午夜的第一个瞬间。这通常不是你想要的。 Oracle以两种方式使这个问题变得更糟:

  1. date数据类型包含时间组件。
  2. 呈现date值的默认方式没有时间组件。
  3. 因此,为了最安全,请使用以下规则:

    • 请勿在日期使用between
    • 使用>=作为第一个日期。
    • 第二个用户<

    Aaron Bertrand对此主题有一个blog。虽然它是专门针对SQL Server的,但许多想法都适用于Oracle - 特别是因为Oracle中的date数据类型包括时间。

答案 1 :(得分:1)

SQL> create table date_tab as select sysdate + level d from dual connect by rownum < 10;

Table created.

使用:

SQL> set autotrace traceonly
SQL> select * from date_tab where d between sysdate + 1 and sysdate + 3;


Execution Plan
----------------------------------------------------------
Plan hash value: 290508398

...

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(SYSDATE@!+1<=SYSDATE@!+3)
   2 - filter("D">=SYSDATE@!+1 AND "D"<=SYSDATE@!+3)

使用日期间隔:

SQL> select * from date_tab where d > sysdate + 1 and d <= sysdate + 3;


Execution Plan
----------------------------------------------------------
Plan hash value: 290508398

...

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(SYSDATE@!+1<SYSDATE@!+3)
   2 - filter("D">SYSDATE@!+1 AND "D"<=SYSDATE@!+3)

正如您所看到的,oracle优化器将between谓词重写为"D">=SYSDATE@!+1 AND "D"<=SYSDATE@!+3因此,如果您使用第二个变体oracle执行的操作比第一个变量执行的操作少一步。