在Oracle 11g中,如何获取两个日期之间的天数?

48
我正在尝试在Oracle 11g中找到两个日期之间的整数天数。 我可以通过以下方式接近:
select sysdate - to_date('2009-10-01', 'yyyy-mm-dd') from dual

但是这返回的是一个时间间隔,我尝试将其转换为整数但未成功。

编辑:显然在10g中,这会返回天数作为一个整数。


5
SQL应该返回一个数值,而不是时间间隔。 - skaffman
2
十多年后,这里有一个db<>fiddle展示了从日期减去日期(例如SYSDATE)和从日期减去时间戳(例如SYSTIMESTAMP)之间的差异。前者产生表示两个日期之间天数计数的数字,而后者产生表示两个日期之间天数的时间间隔表示。实际上,在计算中引入时间戳会返回一个时间间隔,因此也许OP已经重新定义了SYSDATE。 - Bob Jarvis - Слава Україні
6个回答

58

或者你可以这样做:

select trunc(sysdate) - to_date('2009-10-01', 'yyyy-mm-dd') from dual

这将返回一个整天的数字:

SQL> create view v as 
  2  select trunc(sysdate) - to_date('2009-10-01', 'yyyy-mm-dd') diff 
  3  from dual;

View created.

SQL> select * from v;

      DIFF
----------
        29

SQL> desc v
 Name                   Null?    Type
 ---------------------- -------- ------------------------
 DIFF                            NUMBER(38)

3
这仍然返回一个时间间隔类型(INTERVAL DAY TO SECOND)。 - Brian Ramsay
1
不,它并没有,你为什么这么说? - Tony Andrews
1
证明它返回的是数字而不是加上 INTERVAL DAY TO SECOND 的时间间隔。 - Tony Andrews
不是现在相关,但为了完整起见。10g 返回一个 NUMBER,11g 返回一个 INTERVAL DAY TO SECOND。 - Brian Ramsay
@BrianRamsay,你的经历很奇怪,但我可以向你保证,11g也返回了一个数字 - 就像我今天使用的19c一样。如果行为在10g和11g之间发生了变化,那么大量的代码将会被破坏,Oracle将不得不立即发布修复程序!你可以在sqlfiddle.com上确认11g的行为。 - Tony Andrews

27

我自己解决了。我需要

select extract(day from sysdate - to_date('2009-10-01', 'yyyy-mm-dd')) from dual

8
奇怪。与其他回答者一样,当我执行您的原始查询时,我得到一个数字,而不是一个区间。当我尝试您的解决方案时,我遇到了一个错误,ORA-30076:提取源的提取字段无效。这是在Oracle 10g中发生的;您使用的是哪个版本? - Dave Costa
11g。可能就是这样了。谢谢,戴夫。 - Brian Ramsay
使用systimestamp而不是sysdate意味着它执行时间戳而不是日期算术运算,这会产生INTERVAL作为结果。但我无法复制您使用sysdate的经验。 - Gary Myers
2
从双重选择中提取(sysdate - cast(date '2009-10-01' as timestamp))的日期。 - jurijcz
2
我认为@Tony Andrews的回答更好。 - Delali

6
您可以尝试使用以下方法:
select trunc(sysdate - to_date('2009-10-01', 'yyyy-mm-dd')) as days from dual

trunc() 对我不起作用。我收到了这个错误:数据类型不一致:预期是数字,实际得到的是间隔天到秒。 - Brian Ramsay
哦,是的...因为第二个日期中没有HH24:MI:SS部分...很高兴你自己解决了。 - Sabeen Malik

1
  • Full days between end of month and start of today, including the last day of the month:

    SELECT LAST_DAY (TRUNC(SysDate)) - TRUNC(SysDate) + 1 FROM dual
    
  • Days between using exact time:

    SELECT SysDate - TO_DATE('2018-01-01','YYYY-MM-DD') FROM dual
    

1

这个可以运行,我已经测试过了。
它会给出sysdate和从admitdate列获取的日期之间的差异。

  TABLE SCHEMA:
    CREATE TABLE "ADMIN"."DUESTESTING" 
    (   
  "TOTAL" NUMBER(*,0), 
"DUES" NUMBER(*,0), 
"ADMITDATE" TIMESTAMP (6), 
"DISCHARGEDATE" TIMESTAMP (6)
    )

EXAMPLE:
select TO_NUMBER(trunc(sysdate) - to_date(to_char(admitdate, 'yyyy-mm-dd'),'yyyy-mm-dd')) from admin.duestesting where total=300

0
请参考以下查询以获取您的答案。我在第二部分选择了一个虚拟日期,您可以根据您的要求替换它。
SELECT TO_DATE(SysDate,'YYYY-MM-DD')  - TO_DATE('2018-01-01','YYYY-MM-DD') FROM dual

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接