我有一个查询,它涉及到一个where子句,我比较两个数据类型为DATE
的列,它们是last_collected_date
和update_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
的原因吗?
3条答案
按热度按时间o4tp2gmn1#
Oracle中的
DATE
用词不当;它实际上是一个日期时间。2这意味着它总是由一个日期和一个时间组成,如果我们只想查看日期,我们将时间设置为午夜。与
您可能正在比较2023 - 02 - 27 09:00与2023 - 02 - 27 11:00。日期相同,但由于时间不同,
WHERE
子句的结果为true。这一点:
是一种危险的,因为隐藏的隐式转换,并且只在巧合的情况下才对您起作用。
TO_DATE
是一个应用于要转换为日期时间的字符串的函数。Oracle所做的是根据您的会话设置将日期时间转换为字符串,然后再转换回日期时间。您的会话设置似乎是仅限日期的,所以你碰巧在这个过程中丢失了时间部分,并将你的两个日期设置为午夜。如果要比较日期,请将日期时间截断为午夜:
qni6mghb2#
当您这样做时:
那么
TO_DATE
需要一个字符串作为第一个参数,这样您的查询就有效了:如果您的
NLS_DATE_FORMAT
是DD-MON-RR
(或者没有时间组件的等效值),那么您实际上所做的就是将字符串截断到午夜。如果这是您想要的,那么使用
TRUNC
:last_collected_date < update_date
不起作用,但不清楚为什么TRUNC(last_collected_date) < TRUNC(update_date)
起作用,就好像last_collected_date < update_date
为假,那么TRUNC(last_collected_date) < TRUNC(update_date)
也必须为假。*8fq7wneg3#
Oracle dates存储日期和时间。因此,假设以下数据:
您的第一个查询将与此数据匹配,因为上次收集日期早于更新日期,尽管两者在同一日历日。