Sql 如何计算Oracle中两个日期之间的闰年数?
我想计算员工的雇佣日期与当前日期之间的闰年数(在Oracle SQL Developer的hr.employees表中)。如何做到这一点?类似的功能将允许您选择数字,在本例中,从1到2999Sql 如何计算Oracle中两个日期之间的闰年数?,sql,oracle,date,Sql,Oracle,Date,我想计算员工的雇佣日期与当前日期之间的闰年数(在Oracle SQL Developer的hr.employees表中)。如何做到这一点?类似的功能将允许您选择数字,在本例中,从1到2999 Select Rownum year From dual Connect By Rownum <= 2999 选择Rownum year 来自双重 通过Rownum连接类似的内容将允许您选择数字,在本例中,从1到2999 Select Rownum year
Select Rownum year
From dual
Connect By Rownum <= 2999
选择Rownum year
来自双重
通过Rownum连接类似的内容将允许您选择数字,在本例中,从1到2999
Select Rownum year
From dual
Connect By Rownum <= 2999
选择Rownum year
来自双重
通过Rownum连接您可以重用Oracle已经编写的代码:只需检查创建闰日是否引发异常:
SELECT TO_DATE('2016-02-29','YYYY-MM-DD') FROM DUAL;
29.02.2016
但是
因此,您只需计算例外情况:
CREATE OR REPLACE FUNCTION count_leap_years (p_from DATE, p_to DATE) RETURN NUMBER
IS
number_of_leap_days NUMBER := 0;
date_not_valid EXCEPTION;
PRAGMA EXCEPTION_INIT(date_not_valid, -1839);
BEGIN
FOR y IN EXTRACT(YEAR FROM p_from) .. EXTRACT(YEAR FROM p_to) LOOP
DECLARE
d DATE;
BEGIN
d := TO_DATE(to_char(y,'fm0000')||'-02-29', 'YYYY-MM-DD');
IF p_from < d AND d < p_to THEN
number_of_leap_days := number_of_leap_days + 1;
END IF;
EXCEPTION WHEN date_not_valid THEN
NULL;
END;
END LOOP;
RETURN number_of_leap_days;
END count_leap_years;
/
创建或替换函数计数闰年(p_开始日期,p_结束日期)返回编号
是
闰日数:=0;
日期\u无效\u例外情况;
PRAGMA异常初始化(日期无效,-1839);
开始
对于摘录中的y(从p_开始的年份)。。提取(从p_到)循环的年份
声明
d日期;
开始
d:=截止日期(截止日期为年月日);
如果p_from
您可以重用Oracle已经编写的代码:只需检查创建闰日是否引发异常:
SELECT TO_DATE('2016-02-29','YYYY-MM-DD') FROM DUAL;
29.02.2016
但是
因此,您只需计算例外情况:
CREATE OR REPLACE FUNCTION count_leap_years (p_from DATE, p_to DATE) RETURN NUMBER
IS
number_of_leap_days NUMBER := 0;
date_not_valid EXCEPTION;
PRAGMA EXCEPTION_INIT(date_not_valid, -1839);
BEGIN
FOR y IN EXTRACT(YEAR FROM p_from) .. EXTRACT(YEAR FROM p_to) LOOP
DECLARE
d DATE;
BEGIN
d := TO_DATE(to_char(y,'fm0000')||'-02-29', 'YYYY-MM-DD');
IF p_from < d AND d < p_to THEN
number_of_leap_days := number_of_leap_days + 1;
END IF;
EXCEPTION WHEN date_not_valid THEN
NULL;
END;
END LOOP;
RETURN number_of_leap_days;
END count_leap_years;
/
创建或替换函数计数闰年(p_开始日期,p_结束日期)返回编号
是
闰日数:=0;
日期\u无效\u例外情况;
PRAGMA异常初始化(日期无效,-1839);
开始
对于摘录中的y(从p_开始的年份)。。提取(从p_到)循环的年份
声明
d日期;
开始
d:=截止日期(截止日期为年月日);
如果p_from
闰年由366天组成。我假设两个日期之间的“闰年”包括一年中从1月1日到12月31日的所有日子,包括2月29日
基于这种理解,有一个非常简单的解决方案
- 计算雇佣日期后一年的1月1日和结束日期后一年的1月1日之间的天数
- 计算这两个日期之间的年数
- 减去天数和年数之差*365
令人高兴的是,内置函数完成了大部分工作
这导致:
(trunc(sysdate, 'YYYY') -
trunc(hiredate + interval '1' year, 'YYYY') -
365 * (extract(year from sysdate) - extract(year from hiredate) - 1)
) as num_years
计算闰日有点困难,但这不是问题所在。闰年由366天组成。我假设两个日期之间的“闰年”包括一年中从1月1日到12月31日的所有日子,包括2月29日
基于这种理解,有一个非常简单的解决方案
- 计算雇佣日期后一年的1月1日和结束日期后一年的1月1日之间的天数
- 计算这两个日期之间的年数
- 减去天数和年数之差*365
令人高兴的是,内置函数完成了大部分工作
这导致:
(trunc(sysdate, 'YYYY') -
trunc(hiredate + interval '1' year, 'YYYY') -
365 * (extract(year from sysdate) - extract(year from hiredate) - 1)
) as num_years
计算闰日有点困难,但这不是问题所在。试试这个:
CREATE OR REPLACE FUNCTION LEAP_YEARS(EMP_ID IN NUMBER)
RETURN NUMBER
IS
HIRE_YEAR NUMBER:=0;
SYS_YEAR NUMBER:=0;
NUMBER_LEAP_YEARS NUMBER:=0;
BEGIN
SELECT EXTRACT(YEAR FROM HIRE_DATE) INTO HIRE_YEAR
FROM EMPLOYEE
WHERE EMPLOYEE_ID = EMP_ID;
SELECT EXTRACT(YEAR FROM SYSDATE()) INTO SYS_YEAR
FROM DUAL;
FOR IDX IN HIRE_YEAR..SYS_YEAR LOOP
IF MOD(IDX,4)=0 THEN
NUMBER_LEAP_YEARS := NUMBER_LEAP_YEARS + 1;
END IF;
END LOOP;
RETURN NUMBER_LEAP_YEARS;
END;
我测试了一个玩具的例子,它的作品。也许您需要改进它(提示:可能它需要一些例外,并且它假设hire_date
然后您可以将其用作:
SELECT LEAP_YEARS(E.EMPLOYEE_ID) FROM EMPLOYEE E;
试试这个:
CREATE OR REPLACE FUNCTION LEAP_YEARS(EMP_ID IN NUMBER)
RETURN NUMBER
IS
HIRE_YEAR NUMBER:=0;
SYS_YEAR NUMBER:=0;
NUMBER_LEAP_YEARS NUMBER:=0;
BEGIN
SELECT EXTRACT(YEAR FROM HIRE_DATE) INTO HIRE_YEAR
FROM EMPLOYEE
WHERE EMPLOYEE_ID = EMP_ID;
SELECT EXTRACT(YEAR FROM SYSDATE()) INTO SYS_YEAR
FROM DUAL;
FOR IDX IN HIRE_YEAR..SYS_YEAR LOOP
IF MOD(IDX,4)=0 THEN
NUMBER_LEAP_YEARS := NUMBER_LEAP_YEARS + 1;
END IF;
END LOOP;
RETURN NUMBER_LEAP_YEARS;
END;
我测试了一个玩具的例子,它的作品。也许您需要改进它(提示:可能它需要一些例外,并且它假设hire_date
然后您可以将其用作:
SELECT LEAP_YEARS(E.EMPLOYEE_ID) FROM EMPLOYEE E;
假设该员工于2000-01-01被录用;2000年算是闰年吗?2000-03-01和2000-12-31怎么样?假设当前年份为2016年(或2020年,如果您愿意),当前日期为2016-01-01、2016-03-01、2016-12-31——您是否将2016年视为闰年之一?你真的在计算他们就业期间的闰日数吗?还有两个更重要的日期需要考虑:2000-02-29和2016-02-29。当你知道这些边界问题的答案时,剩下的就相对简单了,因为任何日期计算都是“简单的”。还有一些更麻烦的计算领域。你想计算闰日数还是闰年数?如果是后者,你如何定义如果某人在闰年的3月15日和2月15日被雇佣会发生什么?假设该员工在2000-01-01被雇佣;2000年算是闰年吗?2000-03-01和2000-12-31怎么样?假设当前年份为2016年(或2020年,如果您愿意),当前日期为2016-01-01、2016-03-01、2016-12-31——您是否将2016年视为闰年之一?你真的在计算他们就业期间的闰日数吗?还有两个更重要的日期需要考虑:2000-02-29和2016-02-29。当你知道这些边界问题的答案时,剩下的就相对简单了,因为任何日期计算都是“简单的”。还有一些更麻烦的计算领域。你想计算闰日数还是闰年数?如果是后者,您如何定义如果某人在闰年的3月15日和2月15日被雇用会发生什么?您是对的,我更新了响应以正确使用Oracle SQL。函数值和年份在OracleYou是对的,我更新了响应以在Oracle SQL上正常工作。函数值和年份在Oracle中不可用