sql - 在 Oracle 中准确计算过去的年数(考虑闰年)

标签 sql oracle date select

在 Oracle 中,我需要计算自给定日期以来经过的年数从 1 开始的值,考虑闰年

最初的计算没有考虑闰年。这是

CEIL ((SYSDATE- prog_start_dt) / 365))

然后我决定使用MONTHS_BETWEEN,但我的新计算中有一个错误:

CEIL(MONTHS_BETWEEN(SYSDATE, prog_start_dt) / 12)

问题是,如果我正好在 prog_start_date 之后 1 年,无论时间如何,该值都会少 1。例如:

sysdate = 2020-07-01 15:30:00
prog_start_dt = 2019-07-01 00:00:00
--> 1. CEIL ((SYSDATE- prog_start_dt) / 365)) --> Result: 2
--> 2. CEIL(MONTHS_BETWEEN(SYSDATE, prog_start_dt) / 12) --> Result 1

正确的结果是2。因此,我需要顶部公式的行为,但要考虑闰年,这显然不会是 365。有什么好的解决办法吗?

最佳答案

这是a documented behavior :

If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer.

如果您确实想解决这个问题,那么一个选择是添加一些逻辑来处理这种特定情况:当比较的日期属于同一月份和同一天时,然后检查时间部分以查看年份是否已到已过去:

ceil(months_between(sysdate, prog_start_dt) / 12)
+ case when to_char(sysdate, 'mm-dd') = to_char(prog_start_dt, 'mm-dd') 
       and to_char(sysdate, 'hh24:mi') > to_char(prog_start_dt, 'hh24:mi')
    then 1
    else 0
end

<强> Demo on DB Fiddle :

with t as (
    select 
        to_date('2020-07-01 15:30:00', 'yyyy-mm-dd hh24:mi:ss') date1, 
        to_date('2019-07-01 00:00:00' , 'yyyy-mm-dd hh24:mi:ss') date2
    from dual
)
select 
    ceil(months_between(date1, date2) / 12)
    + case when to_char(date1, 'mm-dd') = to_char(date2, 'mm-dd') 
           and to_char(date1, 'hh24:mi') > to_char(date2, 'hh24:mi')
        then 1
        else 0
    end year_diff
from t
| YEAR_DIFF |
| --------: |
|         2 |

关于sql - 在 Oracle 中准确计算过去的年数(考虑闰年),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62686885/

相关文章:

oracle - 如何在 PL/SQL 中创建值持续存在的变量?

python - 我如何使用 Python(精确到分钟)计算过去 30 天的时间?

sql - 从表中选择值作为列标题

mysql - 从两个表中检索数据但排除某些数据

oracle - 如何在不使用 DESCRIBE 子句的情况下描述 ORACLE 包?

java - 以最小的开销插入两个表

具有短日期模式的 java 本地化日期

Python - 日期和时间 : AttributeError: 'module' object has no attribute 'month'

sql - Microsoft SQL Compact Edition 重命名列

java - 无法在 Java 中运行多个 SQL 更新语句