根据给定日期获取上个月的最长日期

时间:2012-12-27 17:05:37

标签: sql oracle

我正在尝试编写一个查询,根据以下条件为我提供max date表单Table_A

如果给定日期(输入参数)在该年4月1日至9月30日之间,则在4月1日之前返回MAX(date)

OR

如果给定日期(输入参数)在下一年的10月1日至3月31日之间,则在10月1日之前返回MAX(date)

例如:

  1. 截止日期为2012年12月27日(日期为10月1日至次年3月31日) 返回2012年9月29日
  2. 鉴于日期为2012年8月17日(日期为4月1日至次年9月30日) 返回日期(4月1日之前的最长日期是3月29日)

2 个答案:

答案 0 :(得分:3)

试试这个:

select max(case
            when trunc(the_date) between to_date('01-apr-'||the_year, 'dd-mon-yyyy')
                                     and to_date('30-sep-'||the_year, 'dd-mon-yyyy')
             and dte < to_date('01-apr-'||the_year, 'dd-mon-yyyy')
            then
              dte
            when trunc(the_date) between to_date('01-oct-'||the_year, 'dd-mon-yyyy')
                                     and to_date('31-mar-'||(the_year+1), 'dd-mon-yyyy')
             and dte < to_date('01-oct-'||the_year, 'dd-mon-yyyy')
            then
              dte
           end) max_date
  from table_a a 
       cross join (select v_inp_date the_date,
                          to_char(add_months(v_inp_date,-3), 'yyyy') the_year
                     from dual) dte;

所以你输入日期在dte部分

v_inp_date

 to_char(add_months(v_inp_date,-3), 'yyyy') the_year

例如一个小测试:

SQL> create table table_a(dte date);

    Table created.

SQL> insert into table_a values(to_date('28-sep-2012', 'dd-mon-yyyy'));

1 row created.

SQL> insert into table_a values(to_date('29-sep-2012', 'dd-mon-yyyy'));

1 row created.

SQL> insert into table_a values(to_date('28-mar-2012', 'dd-mon-yyyy'));

1 row created.

SQL> insert into table_a values(to_date('29-mar-2012', 'dd-mon-yyyy'));

1 row created.

SQL> insert into table_a values(to_date('28-sep-2011', 'dd-mon-yyyy'));

1 row created.

SQL> insert into table_a values(to_date('27-mar-2011', 'dd-mon-yyyy'));

1 row created.

SQL> commit;

Commit complete.

SQL> var inpdate varchar2(20);
SQL> exec :inpdate := '27-dec-2012';

PL/SQL procedure successfully completed.

SQL> select max(case
  2              when trunc(the_date) between to_date('01-apr-'||the_year, 'dd-mon-yyyy')
  3                                       and to_date('30-sep-'||the_year, 'dd-mon-yyyy')
  4               and dte < to_date('01-apr-'||the_year, 'dd-mon-yyyy')
  5              then
  6                dte
  7              when trunc(the_date) between to_date('01-oct-'||the_year, 'dd-mon-yyyy')
  8                                       and to_date('31-mar-'||(the_year+1), 'dd-mon-yyyy')
  9               and dte < to_date('01-oct-'||the_year, 'dd-mon-yyyy')
 10              then
 11                dte
 12             end) max_date
 13    from table_a a
 14         cross join (select to_date(:inpdate,'dd-mon-yyyy') the_date,
 15                            to_char(add_months(to_date(:inpdate,'dd-mon-yyyy'), -3), 'yyyy') the_year
 16                       from dual) dte;

MAX_DATE
---------
29-SEP-12

SQL> exec :inpdate := '17-aug-2012';

PL/SQL procedure successfully completed.

SQL> /

MAX_DATE
---------
29-MAR-12

SQL> exec :inpdate := '01-oct-2011';

PL/SQL procedure successfully completed.

SQL> /

MAX_DATE
---------
28-SEP-11

SQL> exec :inpdate := '01-apr-2011';

PL/SQL procedure successfully completed.

SQL> /

MAX_DATE
---------
27-MAR-11

SQL>

答案 1 :(得分:0)

我的示例中的结束日期是2012年12月31日,您可以将其延长至2013年以上。我正在构建表格 - 每行都会打印max_date。此外,我硬编码最大日期。你不需要做任何这些,这只是例如。将&amp; 1和&amp; 2替换为带引号的数值......:

SELECT date_table --, start_date, end_date
, (CASE WHEN date_table BETWEEN To_Date('01-APR-2012') And To_Date('30-SEP-2012') Then max_apr_date 
        WHEN date_table BETWEEN To_Date('01-OCT-2012') And To_Date('31-DEC-2012') Then max_oct_date
   END) max_date
FROM
(
SELECT *
  FROM
  (
   SELECT TRUNC(SYSDATE,'Y')+LEVEL-1   date_table
        , To_Date('&1')                start_date  
        , To_Date('&2')                end_date 
        , '29-MAR-2012'                max_apr_date 
        , '29-Sep-2012'                max_oct_date
    FROM dual 
    CONNECT BY LEVEL <= (ADD_MONTHS(TRUNC(SYSDATE,'Y'),12)-TRUNC(SYSDATE,'Y') )
  )
   WHERE date_table BETWEEN start_date AND end_date
)
/