为啥 Oracle ADD_MONTHS() 返回的 sysdate 值与我硬编码今天的日期不同?
Posted
技术标签:
【中文标题】为啥 Oracle ADD_MONTHS() 返回的 sysdate 值与我硬编码今天的日期不同?【英文标题】:Why is Oracle ADD_MONTHS() returning a different value for sysdate than if I hardcode today's date?为什么 Oracle ADD_MONTHS() 返回的 sysdate 值与我硬编码今天的日期不同? 【发布时间】:2021-09-02 19:47:36 【问题描述】:我需要提取 6 个月前到现在的所有记录。
起初我硬编码了今天(2021 年 9 月 2 日)的日期并得到了我预期的结果:
select case_no, closed_dt from table1
where closed_dt >= add_months(TO_DATE('09/02/2021', 'mm/dd/yyyy'), -6)
order by closed_dt
这给了我想要的结果,从 2021 年 3 月 2 日到今天的记录列表:
CASE_NO | CLOSED_DT
-------------------
94 | 03/02/2021
57 | 03/03/2021
29 | 07/26/2021
04 | 09/02/2021
但是,此查询将在自动脚本中,因此我无法对日期进行硬编码,我需要将其动态更改为始终为过去 6 个月。所以我尝试使用 sysdate,得到了这个结果:
select case_no, closed_dt from table1
where closed_dt >= add_months(sysdate, -6)
order by closed_dt
结果:
CASE_NO | CLOSED_DT
-------------------
57 | 03/03/2021
29 | 07/26/2021
04 | 09/02/2021
如您所见,3 月 2 日的记录现在没有返回,即使它应该返回。
更令人困惑的是,当我这样做时
select add_months(sysdate, -6) from dual
它按预期返回03/02/2021
。
谁能解释发生了什么,并提供正确的解决方案来使用 sysdate 返回 6 个月前的记录?
【问题讨论】:
一个明显的原因是时区问题。 一个更明显的原因是sysdate
有一个(通常非零)时间组件。您的硬编码相当于在调用add_months()
时使用trunc(sysdate)
,而不是sysdate
。
您能否解释一下,当我从 dual 中选择 sysdate 时,如何使 sysdate 看起来正确,但在更复杂的查询中却无法正常工作?
@mathguy 我尝试使用 trunc(sysdate) 进行查询,现在它可以按预期工作。感谢您的意见。请把它放在答案中,这样我就可以投票了。
【参考方案1】:
Oracle date
始终具有日期和时间组件。 TO_DATE('09/02/2021', 'mm/dd/yyyy')
返回 2021 年 9 月 2 日午夜的日期。另一方面,sysdate
返回当前日期和时间(我的本地计算机上的 2021 年 9 月 2 日 13:51:00)。假设您的表中的数据值是 2021 年 3 月 2 日午夜,那么第一个查询将返回该行,而第二个查询则不会因为时间原因。
我希望您想使用 trunc
函数将时间组件设置为午夜
where closed_dt >= add_months(trunc(sysdate), -6)
【讨论】:
以上是关于为啥 Oracle ADD_MONTHS() 返回的 sysdate 值与我硬编码今天的日期不同?的主要内容,如果未能解决你的问题,请参考以下文章
mysql里有没有类似oracle里的ADD_MONTHS函数,自能的提取间隔的月份
oracle 日期常用函数 (ADD_MONTHS,LAST_DAY,NEXT_DAY,MONTHS_BETWEEN,NEW_TIME,ROUND,TRUNC)