SELECT FROM TABLE by YEAR dynamically - sql

I have a query (in Oracle SQL Developer) which is currently hard-coded to select all records from 2019, 2018, and 2017. Now that it's 2020, I'd like to change this to select going back three years dynamically, so that this query can work years from now without having to change the code.
I know that I can find all records from this specific date last year through the end of the year with -
SELECT * FROM TABLE
WHERE BOOKDATE >= add_months( sysdate, -12*1 );
So that would give me from 11-MAR-2019 through the end of 2019. But how do I select all records for the current year, last year, and two years ago (each year separately) - and not from this date specifically? BOOKDATE has the format DD-MON-YY.

You could extract the year and perform the calculation on it:
SELECT *
FROM mytable
WHERE EXTRACT(YEAR FROM bookdate) - EXTRACT(YEAR FROM SYSDATE) <= 3

You could try like this:
SELECT *
FROM TABLE
WHERE EXTRACT(YEAR from BOOKDATE) >= EXTRACT(YEAR from sysdate)-3

Related

Oracle sql - get months id between two dates

I have date range eg. '2021-01-05' and '2021-02-10'. Two months January and February.
Need resaults:
Months
------
1
2
You want to iterate through the months. This is done with a recursive query in SQL:
with months (month_start_date) as
(
select trunc(:start_date, 'month') from mytable
union all
select month_start_date + interval '1' month
from months
where month_start_date < trunc(:end_date, 'month')
)
select
extract(year from month_start_date) as year,
extract(month from month_start_date) as month
from months
order by month_start_date;
You can use EXTRACT function that Oracle has to achieve this. In your case it should look something like:
SELECT EXTRACT (month FROM date_column) as "Months"
For more information about this function you can check out documentation here.

Oracle SQL - Define the year element of a date dependent on the current month

I am trying to create a view in SQL Developer based on this statement:
SELECT * FROM ORDERS WHERE START_DATE > '01-JUL-2020'
The year element of the date needs to set to the year of the current date if the current month is between July and December otherwise it needs to be the previous year.
The statement below returns the required year but I don't know how to incorporate it (or a better alternative) into the statement above:
select
case
when month(sysdate) > 6 then
year(sysdate)
else
year(sysdate)-1
end year
from dual
Thanks
Oracle doesn't have a built-in month function so I'm assuming that is a user-defined function that you've created. Assuming that's the case, it sounds like you want
where start_date > (case when month(sysdate) > 6
then trunc(sysdate,'yyyy') + interval '6' month
else trunc(sysdate,'yyyy') - interval '6' month
end)
Just subtract six months and compare the dates:
SELECT *
FROM ORDERS
WHERE trunc(add_months(sysdate, -6), 'YYYY') = trunc(start_date, 'YYYY')
This compares the year of the date six months ago to the year on the record -- which seems to be the logic you want.

SQL to check current date with column of type string which stores date in the format MMDD is not 120 days old

Oracle table in my application has a column with name "transaction_date" of type string. It stores date in the format MMDD, where MM = month and DD = day.
Please help me to write a SQL statement which will compare the transaction_date column with the current system date, if transaction_date is less than or equal to 120 days, then fetch the records from the table.
The problem I am facing is, transaction_date in db does not have year just month and day as a string value, so how to check if that value is not more than 120 days, that check should work if value in column is of previous year. For example, SQL should work for the scenario where current system date is lets say 01 feb 2018, and the transaction_date column in table has value "1225" (25th dec of previous year).
As a general disclaimer, your current table design is sub optimal, because a) you are storing dates as text, and b) you are not even storing the year for each date. From what you wrote, it looks like you want to consider all data as having occurred within the last year, from the current date.
One trick we can try here is to compare the MMDD text for each record in your table against TO_CHAR(SYSDATE, 'MMDD'), using the following logic:
If the MMDD is less than or equal to today, then it gets assigned to current year (2018 as of the time of writing this answer)
If the MMDD is greater than today, then it gets assigned to previous year (2017).
Then, we may build dates for each record using the appropriate year and check if it is within 120 days of SYSDATE.
WITH yourTable AS (
SELECT '0101' AS date_col FROM dual UNION ALL
SELECT '1001' FROM dual UNION ALL
SELECT '1027' FROM dual UNION ALL
SELECT '1215' FROM dual
)
SELECT
date_col
FROM yourTable
WHERE
(date_col <= TO_CHAR(SYSDATE, 'MMDD') AND
TO_DATE(date_col || TO_CHAR(SYSDATE, 'YYYY'), 'MMDDYYYY') >= SYSDATE - 120) OR
(date_col > TO_CHAR(SYSDATE, 'MMDD') AND
TO_DATE(date_col ||
TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, -12), 'YEAR'), 'YYYY'), 'MMDDYYYY') >=
SYSDATE - 120);
Demo

select records weekly from Oracle table

I need to select recods from oracle table for the current calendar week based on a date datatype field. Currently I am doing like this:
select * from my_table where enter_date > sysdate -7
If today is Thursday, this query will select records seven days from today which infiltrates to last week on Thursday. Is there a way to select records for the current calendar week dynamically?
If your week starts on a Monday then:
select ...
from ...
where dates >= trunc(sysdate,'IW')
For alternative definitions of the first day of the week, trunc(sysdate,'W') truncates to the day of the week with which the current month began, and trunc(sysdate,'WW') truncates to the day of the week with which the current year began.
See other available truncations here: http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions255.htm#i1002084
to_char(sysdate, 'd') returns day of week in [1..7] range; so try using
select *
from my_table
where enter_date >= trunc(sysdate) - to_char(sysdate, 'd') + 1
Here is the SQLFiddel Demo
Below is the query which you can try
select Table1.*
from Table1
where dates > sysdate - TO_CHAR(SYSDATE,'D')

Querying last 5 years

I want to query all products sold in the last 5 years.
It is possible to do it like this:
select * from products
where time between sysdate-1826 and sysdate
But it there also a nicer way instead of calculating all the days and subtract it from sysdate?
SELECT *
FROM products
WHERE date_column >= add_months( sysdate, -12*5 )
or
SELECT *
FROM products
WHERE date_column >= sysdate - interval '5' year
will both give you all the rows from the last 5 years (though you would generally want to add a TRUNC to remove the time portion unless you really care whether a row was created on Feb 8, 2007 in the morning or in the afternoon).
select * from products
where time > DATE_SUB(NOW(), INTERVAL 5 YEAR)
Date sub will subtract 5 years from now