获取过去5年的12月31日和今天的数据

时间:2017-10-10 12:09:39

标签: sql oracle

我有一个表格,其中的数据填写在每日基础日期上。

Col1 Col2       Date
   1  100 10/10/2017
   2  100  9/10/2017
   3  110  8/10/2017
   4  120  7/10/2017
   5  100  6/10/2017
   6  100  5/10/2017
   7  100 31/12/2016
   8  100 30/12/2016
   9  110 29/12/2016
  10  120 31/12/2015
  11  100 30/12/2015
  12  100 29/12/2015
  13  100 31/12/2014
  14  100 30/12/2014
  15  110 29/12/2014

我的要求是我需要选择过去5年的12月31日的数据以及今天的数据。

我尝试使用此查询

select floor(months_between(date '2016-12-31', date '2017-10-10')/12)
from dual;

但无法确定最终的逻辑。

2 个答案:

答案 0 :(得分:2)

假设您的日期在午夜总是有时间成分,那么:

SELECT *
FROM   your_table
WHERE  your_date_column IN (
         TRUNC( SYSDATE ),
         TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY,
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -12 ),
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -24 ),
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -36 ),
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -48 )
       );

(您需要在截断前1天添加以匹配今天12月31日的情况)

  

我的日期还添加了时间组件。例如:10/10/10 11:51:06 AM

简单的解决方案是在日期使用TRUNC

SELECT *
FROM   your_table
WHERE  TRUNC( your_date_column ) IN (
         TRUNC( SYSDATE ),
         TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY,
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -12 ),
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -24 ),
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -36 ),
         ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -48 )
       );

但是你不能在列上使用索引,并且需要TRUNC( your_date_column )上的基于函数的索引才能使用索引。

可以使用索引的更复杂的解决方案是:

SELECT *
FROM   your_table
WHERE  ( your_date_column >= TRUNC( sysdate )
     AND your_date_column  < TRUNC( sysdate ) + INTERVAL '1' DAY
       )
OR     ( your_date_column >= TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY
     AND your_date_column  < TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' )
       )
OR     ( your_date_column >= ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -12 )
     AND your_date_column  < ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ), -12 )
       )
OR     ( your_date_column >= ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -12 )
     AND your_date_column  < ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ), -24 )
       )
OR     ( your_date_column >= ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -12 )
     AND your_date_column  < ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ), -36 )
       )
OR     ( your_date_column >= ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ) - INTERVAL '1' DAY, -12 )
     AND your_date_column  < ADD_MONTHS( TRUNC( SYSDATE + INTERVAL '1' DAY, 'YYYY' ), -48 )
       );

答案 1 :(得分:0)

您可以使用提取

with test_rows  as (select 1 id, to_date('23/01/2014', 'dd/mm/yyyy') tr from dual union all
                     select 2 id, to_date('10/02/2013', 'dd/mm/yyyy') tr from dual union all
                     select 3 id, to_date('01/03/2014', 'dd/mm/yyyy') tr from dual union all
                     select 11 id, to_date('31/12/2014', 'dd/mm/yyyy') tr from dual union all
                     select 12 id, to_date('31/12/2012', 'dd/mm/yyyy') tr from dual)
select * from test_rows
where EXTRACT(DAY from tr) =31
and EXTRACT(MONTH from tr) = 12
and EXTRACT(YEAR from tr)  > EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE, -(12 * 5)))  

结果

1   11  31/12/2014
2   12  31/12/2012