Find Quarter End Date between a set of Date - Oracle SQL - sql

I'm looking to see if it's possible to filter out a list of quarter ending date within a field containing date from a table.
Below is my code for grabbing a range of dates but how can I modify it to grab just the quarter ending dates? example for 2017 - I would want it to show 2017-03-31,2017-06-31,2017-09-31,2017-12-31.
Thanks.
a.activity_date Between To_Date('2017-01-01', 'YYYY-MM-DD') and To_Date(Trunc(SysDate, 'Q') - 1)

I am thinking:
where activity_date >= date '2017-01-01'
and activity_date < trunc(sysdate, 'q')
and activity_date = trunc(activity_date, 'q') + interval '3' month - interval '1' day
The first two predicates are an adapted version of those of your original query (using date literals, and not using to_date() on what is a date already). The expression that is the right operand of the third predicate computes the end of the quarter for the current date: the logic is truncate the date the beginning of the quarter it belongs to, add 3 months, then substract one day. We can use that value for filtering.
We could also phrase this with bespoke Oracle date arithmetics:
where activity_date >= date '2017-01-01'
and activity_date < trunc(sysdate, 'q')
and activity_date = add_months(trunc(activity_date, 'q'), 3) - 1

Related

Is there a way to use SYSDATE with a weekly date?

So I've been trying to fetch some daily data with SYSDATE on a date type YYYYMMDD as following:
SELECT dates, trunc(calendar_date, 'DD') calendar_dates, weekday_nbr
FROM db.date
WHERE dates BETWEEN to_char(TRUNC(SYSDATE)-2, 'YYYYMMDD') AND to_char(TRUNC(SYSDATE)-1, 'YYYYMMDD')
But now I'm trying to use the same but on a YYYY+MM+Week date type with not much success
I tried using:
SELECT T time, period, fiscal_week
FROM db.time
WHERE time BETWEEN to_char(TRUNC(SYSDATE)-2, 'W') AND to_char(TRUNC(SYSDATE)-1,'W')
With time as a 7 digit number, and period and fiscal week as a 2 digit number
Knowing that there's no way I can truncate such date type, how can TRUNC SYSDATE YYYY+MM+Week to get the data on the last 2 weeks?
Also I was thinking about maybe getting the totals from a set day and then dropping all but the last 2 weeks, but on the long run maybe that would be time consuming.
Knowing that there's no way I can truncate such date type, how can TRUNC SYSDATE YYYY+MM+Week to get the data on the last 2 weeks?
Assuming that your fiscal weeks are from Monday-Sunday then you can truncate to the start of the ISO week (which is always Midnight on Monday) and use that for the basis of the comparison:
SELECT *
FROM db.time
WHERE dates >= TRUNC(SYSDATE, 'IW') - INTERVAL '14' DAY
AND dates < TRUNC(SYSDATE, 'IW')
If you have a column that is for weeks then you should still use a DATE data type and add a CHECK constraint (and can use virtual columns to generate the week and the year):
CREATE TABLE time (
dt DATE
CHECK (dt = TRUNC(dt, 'IW')),
year NUMBER(4,0)
GENERATED ALWAYS AS (EXTRACT(YEAR FROM dt)),
month NUMBER(2,0)
GENERATED ALWAYS AS (EXTRACT(MONTH FROM dt)),
week NUMBER(1,0)
GENERATED ALWAYS AS (FLOOR((dt - TRUNC(dt, 'MM'))/7) + 1),
time VARCHAR2(7)
GENERATED ALWAYS AS (
CAST(
TO_CHAR(dt, 'YYYYMM')
|| (FLOOR((dt - TRUNC(dt, 'MM'))/7) + 1)
AS VARCHAR2(7)
)
)
-- ...
);
fiddle
Then you can use the logic above on the date column.
If you do not have a DATE column then you will need to convert your YYYYMMW number into a DATE and then use the logic above.
For example, if the logic for your fiscal weeks (which you have not described) is that the first week of each month starts on the first Monday of the month then you can convert the YYYYMMW number to a DATE using:
SELECT NEXT_DAY(
TO_DATE(SUBSTR(time, 1, 6), 'YYYYMM') - INTERVAL '1' DAY,
'MONDAY'
) + INTERVAL '7' DAY * (SUBSTR(time, 7, 1) - 1) AS week_start
FROM db.time
and then could use it to filter the table using:
SELECT *
FROM (
SELECT t.*,
NEXT_DAY(
TO_DATE(SUBSTR(time, 1, 6), 'YYYYMM') - INTERVAL '1' DAY,
'MONDAY'
) + INTERVAL '7' DAY * (SUBSTR(time, 7, 1) - 1) AS week_start
FROM db.time t
)
WHERE week_start >= TRUNC(SYSDATE, 'IW') - INTERVAL '14' DAY
AND week_start < TRUNC(SYSDATE, 'IW')
If you have different logic for calculating when fiscal weeks start then you will need to apply that logic to the conversion.

Select rows where max date is less than December 31st of the previous year

I am using Oracle SQL developer. I am trying to select rows where max date is less than December 31st of the previous year. I tried this query below but kept getting an error.
Select ORG_ID, STS_DTE
from Table1
Group By RC_ORG_ID
Having MAX(STS_DTE)< '31-Dec-' || extract (year from SYSDATE-1)
I would use trunc():
having MAX(STS_DTE) < trunc(sysdate, 'YYYY') - interval '1 day'
I'm not sure if you want sysdate - interval '1' day.

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.

current month values in oracle db

how to get current month to date values in oracle 12c sql developer
Select dcc.EMPLOYEECODE, dcc.DUTYID, dtt.DUTYDESC
from DUTYCHART dcc
join DCDUTYCHART dtt
on dcc.RESTCODE = dtt.RESTCODE
and dcc.DUTYID = dtt.DUTYID
and trunc(date) = trunc(sysdate)
Here am getting current date but I want to show current month and previous month, I tried some functions like add-months but it didn't worked for me
You can use :
trunc(sysdate, 'MONTH') -- CURRENT MONTH START DATE
ADD_MONTHS(trunc(sysdate, 'MONTH'), -1) -- PREVIOS MONTH START DATE
If you want to get data of previous month then your query's where clause must include: Replace (trunc(date) = trunc(sysdate)) with one of the following according to your need
trunc(date) BETWEEN ADD_MONTHS(trunc(sysdate, 'MONTH'), -1)
AND trunc(sysdate, 'MONTH') - 1 -- PREVIOUS MONTH'S DATA
trunc(date) >= trunc(sysdate, 'MONTH') -- -- CURRENT MONTH'S DATA
trunc(date) >= ADD_MONTHS(trunc(sysdate, 'MONTH'), -1) -- PREVIOUS AND CURRENT MONTH'S DATA TOGETHER
Cheers!!
For the current month, use:
date >= trunc(sysdate, 'MONTH')
For the previous month, use:
(date >= trunc(sysdate, 'MONTH') - interval '1' month and
date < trunc(sysdate, 'MONTH')
)
There is no reason to truncate date for the comparison.

how to get current year to date and prior year to date in sql

Suppose my date range is current: 01-jan-2015 to 17-Feb-2015.
I need the data for 01-jan-2014 to 17-02-2014 also.
how to write the query in sql?
i want to get the data for these CYD and pYD.
Here is an example in Oracle :
select sysdate - interval '1' year from dual;
The key word 'interval' also exist in other SQL language, like postgres.
To select those ranges of dates from, say, a calendar table, I'd probably write this in standard SQL.
select cal_date from calendar
where cal_date between date '2015-01-01'
and current_date
or cal_date between date '2015-01-01' - interval '1' year
and current_date - interval '1' year
order by cal_date;
If I wanted to identify rows in each range, I'd add literal values.
select 'cyd', cal_date
from calendar
where cal_date between date '2015-01-01'
and current_date
union all
select 'pyd', cal_date
from calendar
where cal_date between date '2015-01-01' - interval '1' year
and current_date - interval '1' year
order by cal_date;