current month values in oracle db - sql

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.

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.

Find Quarter End Date between a set of Date - Oracle 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

Returning a Date Range based on Day of the Month

Select *
From Orders
WHERE (
extract(day from sysdate)<=21
and
to_date(SCHEDULEDATE , 'yyyy/mm/dd') between
to_date((to_char(sysdate, 'YYYY')||'/'||cast((extract(month from sysdate)-1)as char)||'/22'),'yyyy/mm/dd') and to_date((to_char(sysdate,'YYYY')||'/'||cast((extract(month from sysdate))as char)||'/21'),'yyyy/mm/dd')
)
or
(
extract(day from sysdate)>21
and
to_date(SCHEDULEDATE , 'yyyy/mm/dd') between
to_date((to_char(sysdate, 'YYYY')||'/'||cast((extract(month from sysdate))as char)||'/22'),'yyyy/mm/dd') and to_date((to_char(sysdate, 'YYYY')||'/'||cast((extract(month from sysdate)+1)as char)||'/21'),'yyyy/mm/dd')
)
I'm trying to figure out a simple way of returning a set of date ranges based on the day of the Month. If the Day of the month of less than or Equal to I want it to return all orders the have a schedule date between the 22 of the Month before and the 21st of the Current month. If the Day of the month is greater than 21 I would like it return all orders that have a schedule date of the current month up to the end of the month. I've tried to use a case in the where with no luck. What I have now doesn't seem to work either. Any help would be appreciated.
I think this does what you want:
WHERE (extract(day from sysdate) <= 21 and
scheduledate >= add_months(trunc(sysdate, 'MON'), -1) + 21 and
scheduledate < trunc(sysdate, 'MON') + 21
) or
(extract(day from sysdate) > 21 and
trunc(scheduledate, 'MON') = trunc(sysdate, 'MON')
)

Query to 'get the records from the actual month' doesn't get me the records that have a bigger day that the current one

I have the following query to get the records from a table from the current month
select *
from
myTable
where
my_date BETWEEN trunc (sysdate, 'mm') AND SYSDATE;
This query works if the records have a lower day compared to the current one
example: if today is 27/10/2016 and I have a record that have this date: 28/10/2016
The record with date 28/10/2016 is not showing
I insert the records using this format TO_DATE( '28/10/2016 18:02:44', 'dd/mm/yyyy hh24:mi:ss')
I want to show all the records from the curren month even if the day is bigger than the actual date
Either:
select *
from
myTable
where
my_date BETWEEN trunc (sysdate, 'mm') AND add_months(trunc (sysdate, 'mm'),1)- 1/(24*3600)
or
select *
from
myTable
where
trunc(my_date,'mm') = trunc (sysdate, 'mm')
The first is sargable, the second is more readable.
If you need the dates in the current month
trunc(my_date, 'mm') = trunc(sysdate, 'mm')
If you need the dates from the current month and on:
my_date >= trunc(sysdate, 'mm')