Is below example good solution for get previous, current and next year?
x
with cte as(
Select extract(year from sysdate - 365) as year from dual
union all
Select extract(year from sysdate) as year from dual
union all
Select extract(year from sysdate + 365) as year from dual
)
Select * from cte
YEAR
-----
2020
2021
2022
Or any better solution?
Advertisement
Answer
Well, yours isn’t correct for e.g. leap years on the last day of that year. Look at 2020:
SQL> select
2 extract(year from to_date('31.12.2020', 'dd.mm.yyyy') - 365) result
3 from dual;
RESULT
----------
2020
SQL>
See? Turns out that “previous” year for date 31.12.2020
is still 2020
.
ADD_MONTHS
is safer, I guess:
SQL> select
2 extract (year from add_months(to_date('31.12.2020', 'dd.mm.yyyy'), -12)) result
3 from dual;
RESULT
----------
2019
SQL>
SQL> select
2 extract (year from add_months(trunc(sysdate), -12)) previous,
3 extract (year from add_months(trunc(sysdate), 0)) this,
4 extract (year from add_months(trunc(sysdate), 12)) next
5 from dual;
PREVIOUS THIS NEXT
---------- ---------- ----------
2020 2021 2022
SQL>
(this
, of course, doesn’t require add_months
, but I kept it to make query look prettier).
Or, why not simply
SQL> select this - 1 as previous,
2 this,
3 this + 1 as next
4 from (select extract(year from sysdate) as this from dual);
PREVIOUS THIS NEXT
---------- ---------- ----------
2020 2021 2022
SQL>
For 3 rows, use a CTE:
SQL> with temp (this) as
2 (select extract(year from sysdate) from dual)
3 select this - 1 as year from temp union all
4 select this from temp union all
5 select this + 1 from temp;
YEAR
----------
2020
2021
2022
SQL>