oracle怎么递归查询时间,oracle 计算并查询两个日期所横跨的天数列表、月数列表、年数列表(connect by)...

1.情景展示

现在,已知两个日期,根据它俩查询所间隔的所有日期列表,如何实现?

2.原因分析

使用递归查询connect by来实现

3.解决方案

3.1 查询出间隔的天数列表

SELECT TO_CHAR(TO_DATE(‘2020-06-01‘, ‘YYYY-MM-DD‘) + ROWNUM - 1,

‘YYYY-MM-DD‘) AS REGDATE

FROM DUAL

CONNECT BY ROWNUM <=

TRUNC(TO_DATE(‘2020-06-17‘, ‘YYYY-MM-DD‘) -

TO_DATE(‘2020-06-01‘, ‘YYYY-MM-DD‘)) + 1

ORDER BY REGDATE

b043844ea6dc2dd1decd5326188257e9.png

解说:

trunc(date2-date1),得出的是两个日期间隔的整数位数,比方说17-1=16,而我们要查询的是这两个日期所跨的所有时间,所需需要+1,这样,才能包括开始时间date1和结尾date2;

connect by,准确的来说是递归查询SQL,connect by rownum <=17,也就是需要查询17次;

TO_DATE(‘2020-06-01‘, ‘YYYY-MM-DD‘) + ROWNUM - 1,因为rownum是从1开始的,比方说,第一次查询rownum=1,查询出来的日期是6月1号+1=6月2号,实际上该为6月1号,第二次rownum=2,查询出来的日期是6月1号+2=6月3号,实际为6月2号,。。。所以需要-1。

3.2 查询出间隔的月份列表

--查询两个日期所跨过的月份列表

SELECT DISTINCT REGDATE

FROM (SELECT TO_CHAR(TO_DATE(‘2020-01‘, ‘YYYY-MM‘) + ROWNUM - 1, ‘YYYY-MM‘) AS REGDATE

FROM DUAL

CONNECT BY ROWNUM <= TO_DATE(‘2020-06‘, ‘YYYY-MM‘) -

TO_DATE(‘2020-01‘, ‘YYYY-MM‘) + 1)

ORDER BY REGDATE

dce902af0b3c56c102e130e0a0263b2a.png

两个date日期类型相减,得出的是相差的天数

38a4226751693f84215538e116c1aab5.png

横跨153天,也就是最终查询结果是153条数据,涵盖了2020-01到2020-06,需要去重,所以,使用distinct

错误实现方式:

5fe085e8bb38c441c1944a0c0199a37e.png

使用months_between()计算两个日期间的间隔月数+1,其值为6,这个没有问题;

问题处在了:TO_CHAR(TO_DATE(‘2020-01‘, ‘YYYY-MM‘) + ROWNUM - 1, ‘YYYY-MM‘),我们将日期格式化到天,看一下

027344e1c6708544dde34f5131989dff.png

日期+数值,代表的含义是:往指定日期后叠加多少天,也就是不管你数值有多大n,都按天数来计算,并推算出n天后对应的日期。

这样一来,自然是不能再使用months_between()来计算,即使,这个函数本身能够计算出间隔月数。

3.3  查询出间隔的年份列表

ea9805e9ee002e62b0368f0aa1b27d67.png

明白了天数和月数的查询计算方式,这个也就是直接套模板的事儿了。

写在最后

哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

相关推荐:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值