日期时间列中的函数trunc()与AND之间的差异

时间:2018-11-09 11:35:08

标签: sql oracle

这是查询

select 1 from tab1 where
TRUNC(tab1.T_DATE) = TRUNC(to_date('2018-08-31','yyyy-mm-dd'))

类似于此吗?

select 1 from tab1 where    
        tab1.T_DATE >= to_date('2018-08-31','yyyy-mm-dd')
        And tab1.T_DATE < to_date('2018-09-01','yyyy-mm-dd')

然后,当我需要使用Trunc()函数时?我问这个区别是因为我有一个使用Trunc()的查询,并且该查询需要索引(确保我不想使用FBI),所以我将函数替换为AND。但是我担心可能会有所不同。

数据示例:

31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018
31/08/2018 10:19:02 PM
31/08/2018 07:55:01 PM
31/08/2018 1:08:54 PM
31/08/2018 1:18:44 PM
31/08/2018 1:45:34 PM
31/08/2018 1:53:57 PM
31/08/2018 1:59:01 PM
31/08/2018 2:04:19 PM
31/08/2018 4:06:56 PM

2 个答案:

答案 0 :(得分:3)

您在问这些是否等效:

where TRUNC(tab1.T_DATE) = TRUNC(to_date('2018-08-31','yyyy-mm-dd'))

where tab1.T_DATE >= to_date('2018-08-31','yyyy-mm-dd') and
      tab1.T_DATE < to_date('2018-09-01','yyyy-mm-dd')

是的。无论日期如何,它们都将带回T_DATE在2018-08-31的所有值。 TRUNC()应用于日期时,将删除时间部分。因此,不需要在第一个表达式的右侧。

我会这样写:

where tab1.T_DATE >= date '2018-08-31' and
      tab1.T_DATE < date '2018-09-01'

因为这可以在tab1(T_DATE)上使用索引。

答案 1 :(得分:0)

是的,两个查询做的完全相同。

Oracle缺少真实的DATE数据类型。它的DATE实际上是一个DATETIME,它一次又一次地使人们感到困惑:-)您可以使用检查约束来获得真实的数据列,该约束拒绝带有时间部分或触发器的日期删除该部分。

对于您的表中确实有日期时间和两个查询来选择一天中的行:

第一个查询更具可读性。人们通常对此表示反对,认为第二个查询可以从T_DATE列上的索引中受益。但是,由于Oracle具有函数索引功能,因此您将在TRUNC(t_date)上使用索引,并且该参数为空。