从日期获取宿舍

时间:2019-02-22 08:53:48

标签: sql oracle

当用户给您类似2019/02/03的日期时,我的函数应返回类似以下的日期: 2019/02 / 03、2019 / 02 / 02、2019 / 02 / 01、2019 / 01 / 31、2019 / 12 / 31、2019 / 11 / 31、2019 / 09 / 30、2019 / 06/30 ,2019/03 / 31,2018 / 12/31

我的这个函数有一个编译错误,我不确定是什么。

CREATE OR REPLACE FUNCTION rep_datesTest(pdt_ref_date IN DATE)
    RETURN SYS_REFCURSOR IS
        pcr_result SYS_REFCURSOR;
    BEGIN
        OPEN pcr_result FOR
        SELECT  
            trunc(pdt_ref_date) as  pdt_ref_date,
            trunc(pdt_ref_date) - 1 pdt_ref_date_1,
            trunc(pdt_ref_date) - 2 pdt_ref_date_2,
            trunc(pdt_ref_date) - 3 pdt_ref_date_3,             
            add_months(Last_DAY(trunc(trunc(pdt_ref_date) - 3, 'MM')), -1) first_day_of_last_month,
            add_months(Last_DAY(trunc(trunc(pdt_ref_date) - 3, 'MM')), -2) first_day_of_2nd_last_month,
            add_months(Last_DAY(trunc(trunc(pdt_ref_date) - 3, 'MM')), -3) first_day_of_3nd_last_month,        
            add_months(Last_DAY(Case when EXTRACT(MONTH from first_day_of_3nd_last_month)>9 and EXTRACT(MONTH from first_day_of_3nd_last_month)<=12 
                                                        then to_date(EXTRACT(YEAR FROm first_day_of_3nd_last_month)||'-09-30','yyyy-mm-dd') 
                                     when EXTRACT(MONTH from first_day_of_3nd_last_month)<=9 and EXTRACT(MONTH from first_day_of_3nd_last_month)>6
                                                        then to_date(EXTRACT(YEAR FROm first_day_of_3nd_last_month)||'-06-30','yyyy-mm-dd') 
                                     when EXTRACT(MONTH from first_day_of_3nd_last_month)<=6 and EXTRACT(MONTH from first_day_of_3nd_last_month)>3
                                                        then to_date(EXTRACT(YEAR FROm first_day_of_3nd_last_month)||'-03-31','yyyy-mm-dd')  
                                      when EXTRACT(MONTH from first_day_of_3nd_last_month)<=3 and EXTRACT(MONTH from first_day_of_3nd_last_month)>12
                                                        then to_date(EXTRACT(YEAR FROm first_day_of_3nd_last_month)||'-12-31','yyyy-mm-dd')   END              
                                )) first_day_of_last_quarter_1,
            add_months(Last_DAY(trunc(first_day_of_last_quarter_1, 'Q')), -8) first_day_of_last_quarter_2,
            add_months(Last_DAY(trunc(first_day_of_last_quarter_1, 'Q')), -11) first_day_of_last_quarter_3,
            add_months(Last_DAY(trunc(first_day_of_last_quarter_1, 'Q')), -14) first_day_of_last_quarter_4,
            add_months(Last_DAY(trunc(first_day_of_last_quarter_1, 'Q')), -17) first_day_of_last_quarter_5
        FROM dual;

        RETURN pcr_result;
    END;

2 个答案:

答案 0 :(得分:1)

我相信你想要

SELECT trunc(pdt_ref_date) - 0 AS pdt_ref_date,
       trunc(pdt_ref_date) - 1 AS pdt_ref_date_1,
       trunc(pdt_ref_date) - 2 AS pdt_ref_date_2,
       trunc(pdt_ref_date) - 3 AS pdt_ref_date_3,             
       add_months(trunc(pdt_ref_date, 'MM'), -0)-1 AS first_day_of_last_month,
       add_months(trunc(pdt_ref_date, 'MM'), -1)-1 AS first_day_of_2nd_last_month,
       add_months(trunc(pdt_ref_date, 'MM'), -2)-1 AS first_day_of_3nd_last_month,
       add_months(trunc(pdt_ref_date, 'Q'), -0)-1  AS first_day_of_last_quarter_1,
       add_months(trunc(pdt_ref_date, 'Q'), -3)-1  AS first_day_of_last_quarter_2,
       add_months(trunc(pdt_ref_date, 'Q'), -6)-1  AS first_day_of_last_quarter_3,
       add_months(trunc(pdt_ref_date, 'Q'), -9)-1  AS first_day_of_last_quarter_4,
       add_months(trunc(pdt_ref_date, 'Q'), -12)-1 AS first_day_of_last_quarter_5
FROM   dual;
PDT_REF_DATE | PDT_REF_DATE_1 | PDT_REF_DATE_2 | PDT_REF_DATE_3 | FIRST_DAY_OF_LAST_MONTH | FIRST_DAY_OF_2ND_LAST_MONTH | FIRST_DAY_OF_3ND_LAST_MONTH | FIRST_DAY_OF_LAST_QUARTER_1 | FIRST_DAY_OF_LAST_QUARTER_2 | FIRST_DAY_OF_LAST_QUARTER_3 | FIRST_DAY_OF_LAST_QUARTER_4 | FIRST_DAY_OF_LAST_QUARTER_5
:----------- | :------------- | :------------- | :------------- | :---------------------- | :-------------------------- | :-------------------------- | :-------------------------- | :-------------------------- | :-------------------------- | :-------------------------- | :--------------------------
03-FEB-19    | 02-FEB-19      | 01-FEB-19      | 31-JAN-19      | 31-JAN-19               | 31-DEC-18                   | 30-NOV-18                   | 31-DEC-18                   | 30-SEP-18                   | 30-JUN-18                   | 31-MAR-18                   | 31-DEC-17                  

db <>提琴here

答案 1 :(得分:0)

以下是使用记录的解决方案(基于MT0的SQL答案):

CREATE OR REPLACE PACKAGE your_package
AS

  TYPE date_info_rec IS RECORD (pdt_ref_date DATE,
                                pdt_ref_date_1 DATE,
                                pdt_ref_date_2 DATE,
                                pdt_ref_date_3 DATE,
                                first_day_of_last_month DATE,
                                first_day_of_2nd_last_month DATE,
                                first_day_of_3rd_last_month DATE,
                                first_day_of_last_quarter_1 DATE,
                                first_day_of_last_quarter_2 DATE,
                                first_day_of_last_quarter_3 DATE,
                                first_day_of_last_quarter_4 DATE,
                                first_day_of_last_quarter_5 DATE);

  FUNCTION your_function (in_date IN DATE)
  RETURN date_info_rec;

END your_package;
/

CREATE OR REPLACE PACKAGE BODY your_package
AS

  FUNCTION your_function (in_date IN DATE)
  RETURN date_info_rec
  IS
    v_date_rec date_info_rec;
  BEGIN
    v_date_rec.pdt_ref_date                := trunc(in_date);
    v_date_rec.pdt_ref_date_1              := trunc(in_date) - 1;
    v_date_rec.pdt_ref_date_2              := trunc(in_date) - 2;
    v_date_rec.pdt_ref_date_3              := trunc(in_date) - 3;
    v_date_rec.first_day_of_last_month     := trunc(in_date, 'MM') - 1;
    v_date_rec.first_day_of_2nd_last_month := add_months(trunc(in_date, 'MM'), -0) - 1;
    v_date_rec.first_day_of_3rd_last_month := add_months(trunc(in_date, 'MM'), -0) - 1;
    v_date_rec.first_day_of_last_quarter_1 := trunc(in_date, 'Q') - 1;
    v_date_rec.first_day_of_last_quarter_2 := add_months(trunc(in_date, 'Q'), -3) - 1;
    v_date_rec.first_day_of_last_quarter_3 := add_months(trunc(in_date, 'Q'), -6) - 1;
    v_date_rec.first_day_of_last_quarter_4 := add_months(trunc(in_date, 'Q'), -9) - 1;
    v_date_rec.first_day_of_last_quarter_5 := add_months(trunc(in_date, 'Q'), -12) - 1;

    RETURN v_date_rec;
  END;

END your_package;
/

如何调用函数的示例:

DECLARE
  v_date DATE;
  v_pop_date_rec your_package.date_info_rec;
BEGIN
  v_date := SYSDATE;

  v_pop_date_rec := your_package.your_function(in_date => v_date);

  -- Demonstrate the output
  dbms_output.put_line('v_pop_date_rec.pdt_ref_date = '||to_char(v_pop_date_rec.pdt_ref_date, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.pdt_ref_date_1 = '||to_char(v_pop_date_rec.pdt_ref_date_1, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.pdt_ref_date_2 = '||to_char(v_pop_date_rec.pdt_ref_date_2, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.pdt_ref_date_3 = '||to_char(v_pop_date_rec.pdt_ref_date_3, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_last_month = '||to_char(v_pop_date_rec.first_day_of_last_month, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_2nd_last_month = '||to_char(v_pop_date_rec.first_day_of_2nd_last_month, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_3rd_last_month = '||to_char(v_pop_date_rec.first_day_of_3rd_last_month, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_last_quarter_1 = '||to_char(v_pop_date_rec.first_day_of_last_quarter_1, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_last_quarter_2 = '||to_char(v_pop_date_rec.first_day_of_last_quarter_2, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_last_quarter_3 = '||to_char(v_pop_date_rec.first_day_of_last_quarter_3, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_last_quarter_4 = '||to_char(v_pop_date_rec.first_day_of_last_quarter_4, 'dd/mm/yyyy'));
  dbms_output.put_line('v_pop_date_rec.first_day_of_last_quarter_5 = '||to_char(v_pop_date_rec.first_day_of_last_quarter_5, 'dd/mm/yyyy'));
END;
/

v_pop_date_rec.pdt_ref_date = 22/02/2019
v_pop_date_rec.pdt_ref_date_1 = 21/02/2019
v_pop_date_rec.pdt_ref_date_2 = 20/02/2019
v_pop_date_rec.pdt_ref_date_3 = 19/02/2019
v_pop_date_rec.first_day_of_last_month = 31/01/2019
v_pop_date_rec.first_day_of_2nd_last_month = 31/01/2019
v_pop_date_rec.first_day_of_3rd_last_month = 31/01/2019
v_pop_date_rec.first_day_of_last_quarter_1 = 31/12/2018
v_pop_date_rec.first_day_of_last_quarter_2 = 30/09/2018
v_pop_date_rec.first_day_of_last_quarter_3 = 30/06/2018
v_pop_date_rec.first_day_of_last_quarter_4 = 31/03/2018
v_pop_date_rec.first_day_of_last_quarter_5 = 31/12/2017