我有一个表格,其中的数据填写在每日基础日期上。
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;
但无法确定最终的逻辑。
答案 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