两个日期列比较oracle未按预期工作

chhkpiq4  于 2023-03-01  发布在  Oracle
关注(0)|答案(3)|浏览(151)

我有一个查询,它涉及到一个where子句,我比较两个数据类型为DATE的列,它们是last_collected_dateupdate_date

SELECT *
FROM mytable
WHERE last_collected_date < update_date;

奇怪的是,这并不像预期的那样工作,我得到的last_collected_date的日期与update_date的日期相同。
但是,当我使用to_date函数时:

SELECT *
FROM mytable
WHERE to_date(last_collected_date) < to_date(update_date);

它按预期工作。为什么会这样?oracle在select语句中内部将日期转换为字符串吗?
这是我的NLS设置。这是我看不到我的hh:mi:ss的原因吗?

o4tp2gmn

o4tp2gmn1#

Oracle中的DATE用词不当;它实际上是一个日期时间。2这意味着它总是由一个日期和一个时间组成,如果我们只想查看日期,我们将时间设置为午夜。

WHERE last_collected_date < update_date

您可能正在比较2023 - 02 - 27 09:00与2023 - 02 - 27 11:00。日期相同,但由于时间不同,WHERE子句的结果为true。
这一点:

WHERE to_date(last_collected_date) < to_date(update_date)

是一种危险的,因为隐藏的隐式转换,并且只在巧合的情况下才对您起作用。TO_DATE是一个应用于要转换为日期时间的字符串的函数。Oracle所做的是根据您的会话设置将日期时间转换为字符串,然后再转换回日期时间。您的会话设置似乎是仅限日期的,所以你碰巧在这个过程中丢失了时间部分,并将你的两个日期设置为午夜。
如果要比较日期,请将日期时间截断为午夜:

WHERE last_collected_date < TRUNC(update_date)
qni6mghb

qni6mghb2#

当您这样做时:

SELECT *
FROM   mytable
WHERE  to_date(last_collected_date) < to_date(update_date);

那么TO_DATE需要一个字符串作为第一个参数,这样您的查询就有效了:

SELECT *
FROM   mytable
WHERE  TO_DATE(
         TO_CHAR(
           last_collected_date,
           (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
         ),
         (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
       )
       <
       TO_DATE(
         TO_CHAR(
           update_date,
           (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
         ),
         (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
       );

如果您的NLS_DATE_FORMATDD-MON-RR(或者没有时间组件的等效值),那么您实际上所做的就是将字符串截断到午夜。
如果这是您想要的,那么使用TRUNC

SELECT *
FROM   mytable
WHERE  TRUNC(last_collected_date) < TRUNC(update_date);
  • 但是,不清楚为什么last_collected_date < update_date不起作用,但不清楚为什么TRUNC(last_collected_date) < TRUNC(update_date)起作用,就好像last_collected_date < update_date为假,那么TRUNC(last_collected_date) < TRUNC(update_date)也必须为假。*
8fq7wneg

8fq7wneg3#

Oracle dates存储日期和时间。因此,假设以下数据:

last_collected_date | update_date
2023-02-27 12:34:56 | 2023-02-27 23:00:00

您的第一个查询将与此数据匹配,因为上次收集日期早于更新日期,尽管两者在同一日历日。

相关问题