Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何计算Oracle中两个日期之间的闰年数?_Sql_Oracle_Date - Fatal编程技术网

Sql 如何计算Oracle中两个日期之间的闰年数?

Sql 如何计算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

我想计算员工的雇佣日期与当前日期之间的闰年数(在Oracle SQL Developer的hr.employees表中)。如何做到这一点?

类似的功能将允许您选择数字,在本例中,从1到2999

    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中不可用