【问题标题】:Using a complete date field in a oracle sql where clause在 oracle sql where 子句中使用完整的日期字段
【发布时间】:2017-09-18 12:19:53
【问题描述】:

我正在尝试创建一个 where 子句,它可以返回带有下表的日期时间间隔,更具体地说,我正在使用此查询:

select *
from tb_alarms c
where to_char(c.e3timestamp, 'dd/mm/yyyy hh24:mi') >= '13/09/2017 16:00'
and   to_char(c.e3timestamp, 'dd/mm/yyyy hh24:mi') <= '14/09/2017 07:05'

但是,此查询返回带有 e3timestamp 字段的行,其值从 14/06/2011 07:49:29 开始,到 14/09/2017 07:04:30 结束。

为什么它返回 2011 年的日期?是因为它比较的是字符而不是日期类型吗?

你们能帮我或指出我可以学习如何使用完整的日期时间间隔执行正确的 where 子句的来源吗?

谢谢!

OBS:e3timestamp 是 tb_alarms 表中 Date 类型的字段。

【问题讨论】:

  • 为什么不能换一种方式比较呢? where c.e3timestamp &gt; = to_date('13/09/2017 16:00', 'dd/mm/yyyy hh24:mi')?

标签: sql oracle datetime


【解决方案1】:

为什么它返回 2011 年的日期?是因为它比较的是字符而不是日期类型吗?

是的,'13/09/2017 16:00' 是字符串文字而不是日期文字 - 查询会将过滤条件的左侧和右侧作为字符串而不是日期进行比较。

所以这些都是真的:

'13/09/2017 16:00' <= '14/09/0001 00:00'
'14/09/0001 00:00' <= '14/09/2017 07:05'

您想使用时间戳文字:

select *
from tb_alarms c
where c.e3timestamp BETWEEN TIMESTAMP '2017-09-13 16:00:00'
                        AND TIMESTAMP '2017-09-14 07:05:00'

或在您的字符串文字上使用TO_DATE,而不是在您的日期/时间戳列上使用TO_CHAR

select *
from tb_alarms c
where c.e3timestamp >= TO_DATE( '13/09/2017 16:00', 'DD/MM/YYYY HH24:MI' )
AND   c.e3timestamp <= TO_DATE( '14/09/2017 07:05', 'DD/MM/YYYY HH24:MI' )

【讨论】:

  • 解释得很好。
【解决方案2】:

您必须使用 to_date 而不是 to_char,同时避免在列上使用函数,因为这会妨碍索引的使用:

select *
from tb_alarms c
where c.e3timestamp between to_date('13/09/2017 16:00','dd/mm/yyyy hh24:mi')
and   to_date('14/09/2017 07:05','dd/mm/yyyy hh24:mi');

【讨论】:

    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2016-09-07
    • 1970-01-01
    • 2021-11-12
    相关资源
    最近更新 更多