Oracle SQL - Fiscal Week of Year - sql

I want to calculate the Fiscal Week of the Year with the following rules:
The fiscal year always starts on June/01
The week always starts on Sunday
Samples are provided for 2019 but ideally it should work for any year
A few samples of correct values are provided with the screenshot attached
I tried to do something like TO_NUMBER(TO_CHAR(TO_DATE(DATE_ID + 1,'DD-Mon-YY'),'IW')) -21 but towards the end of the Calendar year I start to get negatives
SELECT
DATE_ID
, WEEK_OF_YEAR
FROM DATE_DIM
WHERE
DATE_ID IN
(
20190601
, 20190602
, 20190915
, 20191228
, 20191229
, 20200101
, 20200601
, 20200606
, 20200607
)
ORDER BY DATE_ID ASC
;

SELECT TO_CHAR(ADD_MONTHS(SYSDATE,+7),'IW')
FROM dual
Or in your case,
SELECT date_id,TO_CHAR(ADD_MONTHS(TO_DATE(date_id,'YYYYMMDD'),+7),'IW') week_of_year
FROM date_dim
If you don't like the ISO dating where week 1 is the week beginning Sunday during which the 1st of the year falls, you can try offsetting it by moving it back to the previous sunday (TRUNC(..,'D'), then advance a week, then add the 7 months. See if this works for you:
SELECT date_id, TO_CHAR(ADD_MONTHS(TRUNC(date_id,'D') + 7,7),'IW') week_of_year
FROM date_dim

You got confused with your date formats ('yyyymmdd' vs. 'DD-Mon-YY'), so I am using a real date (mydate) in my answer. Convert your string or number to a proper date and you are there :-)
The important thing is to check whether your date is >= June 1. Once this is done you can subtract that year's June 1 or the previous year's one. Well, more or less :-)
select
mydate,
to_char(mydate, 'DY') as tag,
trunc
(
case when to_char(mydate, 'mmdd') >= '0601' then
trunc(mydate + 1, 'iw') + 6 - to_date(to_char(mydate, 'yyyy') || '0601', 'yyyymmdd')
else
trunc(mydate + 1, 'iw') + 6 - to_date(to_char(extract(year from mydate) - 1) || '0601', 'yyyymmdd')
end / 7
) + 1 as fiscal_week
from ...
order by mydate;
Demo: https://dbfiddle.uk/N5pX_5cV

UPDATED ANSWER
You can try this - provide the date like 31-MAY-19 to start your calendar from 01-JUN-19 and define how many days you want. There is a shift of 5 months as the code was taken from my regular calendar and adjusted the start of week to sunday...Tested OK for periods up to 2 years per run. So if you want 6 years you'll have to run this 3 times...
WITH
base_calendar AS
(
SELECT CurrDate AS Day_ID,
TO_CHAR(CurrDate,'Day') AS Week_Day_Full,
TO_CHAR(CurrDate,'DY') AS Week_Day_Short,
TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'D'))) AS Day_Num_of_Week,
--
MAX(CASE WHEN To_Char(CurrDate, 'ddmm') = '2902' THEN EXTRACT(YEAR From CurrDate) END) OVER(Order By CurrDate Rows Between Unbounded Preceding And Current Row) AS last_leap_year,
Count(CASE WHEN ( TO_CHAR(CurrDate,'DY') = 'SUN' And
CurrDate Between To_date('01.06.' || To_Char(EXTRACT(YEAR From CurrDate)), 'dd.mm.yyyy') And To_date('31.05.' || To_Char(EXTRACT(YEAR From CurrDate) + 1), 'dd.mm.yyyy') )
OR
( TO_CHAR(CurrDate,'DY') = 'SUN' And
CurrDate Between To_date('01.06.' || To_Char(EXTRACT(YEAR From CurrDate) - 1), 'dd.mm.yyyy') And To_date('31.05.' || To_Char(EXTRACT(YEAR From CurrDate) ), 'dd.mm.yyyy') )
THEN 1
END) OVER(Order By CurrDate Rows Between Unbounded Preceding And Current Row) AS cnt_sundays
FROM
(
SELECT level n,
-- Calendar starts at the day after this date
TO_DATE('31/05/2019','DD/MM/YYYY') + NUMTODSINTERVAL(level,'DAY') CurrDate
FROM dual
-- Change for the number of days to be added to the table.
CONNECT BY level <= 731
)
)
SELECT DISTINCT
day_id,
CASE WHEN (cnt_sundays + 1 ) - ( (EXTRACT(YEAR From Add_Months(Day_id, - 5)) -EXTRACT(YEAR From MIN(Day_id) OVER()) ) * 53) >= 54 THEN 1
WHEN EXTRACT(YEAR From day_id) <> last_leap_year And day_id > = To_Date('01.06.' || To_Char(EXTRACT(YEAR From day_id)), 'dd.mm.yyyy' )
THEN (cnt_sundays + 1) - ( (EXTRACT(YEAR From Add_Months(Day_id, - 5)) -EXTRACT(YEAR From MIN(Day_id) OVER()) ) * 53) + 1
ELSE (cnt_sundays + 1) - ( (EXTRACT(YEAR From Add_Months(Day_id, - 5)) -EXTRACT(YEAR From MIN(Day_id) OVER()) ) * 53)
END week_of_year,
--
week_day_full,
week_day_short,
CASE week_day_short
WHEN 'SUN' THEN 1
WHEN 'MON' THEN 2
WHEN 'TUE' THEN 3
WHEN 'WED' THEN 4
WHEN 'THU' THEN 5
WHEN 'FRI' THEN 6
WHEN 'SAT' THEN 7
END AS day_num_of_week
FROM base_calendar
ORDER BY day_id
R E S U L T S :
DAY_ID WEEK_OF_YEAR WEEK_DAY_FULL WEEK_DAY_SHORT DAY_NUM_OF_WEEK
--------- ------------ ------------- -------------- ---------------
01-JUN-19 1 Saturday SAT 7
02-JUN-19 2 Sunday SUN 1
03-JUN-19 2 Monday MON 2
04-JUN-19 2 Tuesday TUE 3
05-JUN-19 2 Wednesday WED 4
... ...
... ...
13-SEP-19 16 Friday FRI 6
14-SEP-19 16 Saturday SAT 7
15-SEP-19 17 Sunday SUN 1
16-SEP-19 17 Monday MON 2
... ...
30-DEC-19 32 Monday MON 2
31-DEC-19 32 Tuesday TUE 3
01-JAN-20 32 Wednesday WED 4
02-JAN-20 32 Thursday THU 5
...
27-FEB-20 40 Thursday THU 5
28-FEB-20 40 Friday FRI 6
29-FEB-20 40 Saturday SAT 7
01-MAR-20 41 Sunday SUN 1
02-MAR-20 41 Monday MON 2
...
29-MAY-20 53 Friday FRI 6
30-MAY-20 53 Saturday SAT 7
31-MAY-20 1 Sunday SUN 1
01-JUN-20 1 Monday MON 2
02-JUN-20 1 Tuesday TUE 3
03-JUN-20 1 Wednesday WED 4
04-JUN-20 1 Thursday THU 5
05-JUN-20 1 Friday FRI 6
06-JUN-20 1 Saturday SAT 7
07-JUN-20 2 Sunday SUN 1
... ...
... ...
22-MAY-21 51 Saturday SAT 7
23-MAY-21 52 Sunday SUN 1
24-MAY-21 52 Monday MON 2
25-MAY-21 52 Tuesday TUE 3
26-MAY-21 52 Wednesday WED 4
27-MAY-21 52 Thursday THU 5
28-MAY-21 52 Friday FRI 6
29-MAY-21 52 Saturday SAT 7
30-MAY-21 53 Sunday SUN 1
31-MAY-21 53 Monday MON 2
731 rows selected
... with year 2025 - part of the result mentioned in comments above ...
... ...
29-MAY-25 53 Thursday THU 5
30-MAY-25 53 Friday FRI 6
31-MAY-25 53 Saturday SAT 7
01-JUN-25 1 Sunday SUN 1
02-JUN-25 1 Monday MON 2
03-JUN-25 1 Tuesday TUE 3
04-JUN-25 1 Wednesday WED 4
05-JUN-25 1 Thursday THU 5
06-JUN-25 1 Friday FRI 6
07-JUN-25 1 Saturday SAT 7
08-JUN-25 2 Sunday SUN 1
... ...

Related

How to get last N week data in different year

I need to get last 6 weeks data from some table, right now the logic that I use is this
WEEK([date column]) BETWEEN WEEK(NOW()) - 6 AND WEEK(NOW())
It run as I want, but January is near and I realize that this query will not working as it is. I try to run my query on 15th January 2022, I only get data from 1st January to 15th January when I use my logic.
TGL MINGGU_KE
2022-01-01 | 1
2022-01-02 | 2
2022-01-03 | 2
2022-01-04 | 2
2022-01-05 | 2
2022-01-06 | 2
2022-01-07 | 2
2022-01-08 | 2
2022-01-09 | 3
2022-01-10 | 3
2022-01-11 | 3
2022-01-12 | 3
2022-01-13 | 3
2022-01-14 | 3
2022-01-15 | 3
Can I get the last 6 weeks data including last year?
This is my dbfiddle: https://dbfiddle.uk/o9BeAFJF
You can round the dates to the first day of the week using ROUND, TRUNC or THIS_WEEK
WITH
SEARCH_WEEK (TGL) AS (
VALUES date '2020-12-01'
UNION ALL
SELECT tgl + 1 DAY FROM SEARCH_WEEK WHERE tgl < CURRENT date
),
BASE_DATE (base_date) AS (
VALUES date '2022-01-15'
),
OPTIONS (OPTION, OPTION_BASE_DATE) AS (
SELECT OPTION, option_base_date FROM base_date CROSS JOIN LATERAL (
VALUES
('ROUND D', ROUND(base_date, 'D')),
('ROUND IW', ROUND(base_date, 'IW')),
('ROUND W', ROUND(base_date, 'W')),
('ROUND WW', ROUND(base_date, 'WW')),
('TRUNC D', TRUNC(base_date, 'D')),
('TRUNC IW', TRUNC(base_date, 'IW')),
('TRUNC W', TRUNC(base_date, 'W')),
('TRUNC WW', TRUNC(base_date, 'WW')),
('THIS_WEEK', THIS_WEEK(base_date)),
('THIS_WEEK + 1 DAY', THIS_WEEK(base_date) + 1 DAY)
) a (OPTION, OPTION_BASE_DATE)
)
SELECT
OPTION,
MIN(TGL) BEGIN,
max(tgl) END,
dayname(MIN(TGL)) day_BEGIN,
dayname(max(tgl)) day_end,
days_between(max(tgl), min(tgl)) + 1 duration_in_days
FROM
SEARCH_WEEK
CROSS JOIN options
WHERE
TGL BETWEEN option_base_date - 35 DAYS AND option_base_date + 6 DAYS
GROUP BY OPTION
OPTION
BEGIN
END
DAY_BEGIN
DAY_END
DURATION_IN_DAYS
ROUND D
2021-12-12
2022-01-22
Sunday
Saturday
42
ROUND IW
2021-12-13
2022-01-23
Monday
Sunday
42
ROUND W
2021-12-11
2022-01-21
Saturday
Friday
42
ROUND WW
2021-12-11
2022-01-21
Saturday
Friday
42
THIS_WEEK
2021-12-05
2022-01-15
Sunday
Saturday
42
THIS_WEEK + 1 DAY
2021-12-06
2022-01-16
Monday
Sunday
42
TRUNC D
2021-12-05
2022-01-15
Sunday
Saturday
42
TRUNC IW
2021-12-06
2022-01-16
Monday
Sunday
42
TRUNC W
2021-12-11
2022-01-21
Saturday
Friday
42
TRUNC WW
2021-12-11
2022-01-21
Saturday
Friday
42
fiddle
you can use dateadd to get first day of week six weeks ago like this:
Select * from tableName
where [dateColumn] between dateadd(WEEK,-6,getdate()) and getdate()
You can use DATEADD to get last 6 weeks of data as follows:
Select * from [TableName] where [DateColumn] between
DATEADD(WEEK,-6,GETDATE()) and GETDATE();

Get the last 4 weeks prior to current week of and the same 4 weeks of last year

I have a list of date, fiscal week, and fiscal year:
DATE_VALUE FISCAL_WEEK FISCAL_YEAR_VALUE
14-Dec-20 51 2020
15-Dec-20 51 2020
16-Dec-20 51 2020
17-Dec-20 51 2020
18-Dec-20 51 2020
19-Dec-20 51 2020
20-Dec-20 51 2020
21-Dec-20 52 2020
22-Dec-20 52 2020
23-Dec-20 52 2020
24-Dec-20 52 2020
25-Dec-20 52 2020
26-Dec-20 52 2020
27-Dec-20 52 2020
28-Dec-20 1 2021
29-Dec-20 1 2021
30-Dec-20 1 2021
31-Dec-20 1 2021
1-Jan-21 1 2021
2-Jan-21 1 2021
3-Jan-21 1 2021
4-Jan-21 2 2021
5-Jan-21 2 2021
6-Jan-21 2 2021
7-Jan-21 2 2021
8-Jan-21 2 2021
9-Jan-21 2 2021
10-Jan-21 2 2021
11-Jan-21 3 2021
12-Jan-21 3 2021
13-Jan-21 3 2021
14-Jan-21 3 2021
15-Jan-21 3 2021
16-Jan-21 3 2021
17-Jan-21 3 2021
18-Jan-21 4 2021
19-Jan-21 4 2021
20-Jan-21 4 2021
21-Jan-21 4 2021
22-Jan-21 4 2021
23-Jan-21 4 2021
24-Jan-21 4 2021
20-Dec-21 52 2021
21-Dec-21 52 2021
22-Dec-21 52 2021
23-Dec-21 52 2021
24-Dec-21 52 2021
25-Dec-21 52 2021
26-Dec-21 52 2021
27-Dec-21 53 2021
28-Dec-21 53 2021
29-Dec-21 53 2021
30-Dec-21 53 2021
31-Dec-21 53 2021
1-Jan-22 53 2021
2-Jan-22 53 2021
3-Jan-22 1 2022
4-Jan-22 1 2022
5-Jan-22 1 2022
6-Jan-22 1 2022
7-Jan-22 1 2022
8-Jan-22 1 2022
9-Jan-22 1 2022
10-Jan-22 2 2022
11-Jan-22 2 2022
12-Jan-22 2 2022
13-Jan-22 2 2022
14-Jan-22 2 2022
15-Jan-22 2 2022
16-Jan-22 2 2022
17-Jan-22 3 2022
18-Jan-22 3 2022
19-Jan-22 3 2022
20-Jan-22 3 2022
21-Jan-22 3 2022
22-Jan-22 3 2022
23-Jan-22 3 2022
24-Jan-22 4 2022
25-Jan-22 4 2022
26-Jan-22 4 2022
27-Jan-22 4 2022
28-Jan-22 4 2022
29-Jan-22 4 2022
30-Jan-22 4 2022
I want to pull the last 4 weeks prior to the current week AND the same 4 weeks of the year before. Please see example 1. This works fine when all 4 weeks are within the same year. But when it comes to the beginning of a year when 1 or more weeks are in the current year but the other are in the previous year, I am not able to get the desired output below:
FISCAL_YEAR_VALUE FISCAL_WEEK
2020 51
2020 52
2021 2
2021 1
2021 52
2021 53
2022 1
2022 2
The code I have is below. I am using the date of 21-JAN-22 as an example:
SELECT
FISCAL_YEAR_VALUE,
FISCAL_WEEK
FROM TABLE_NAME
WHERE FISCAL_YEAR_VALUE IN (SELECT *
FROM (WITH T AS (
SELECT DISTINCT FISCAL_YEAR_VALUE
FROM TABLE_NAME
WHERE TRUNC(DATE_VALUE) <= TRUNC(TO_DATE('21-JAN-22'))--TEST DATE
ORDER BY FISCAL_YEAR_VALUE DESC
FETCH NEXT 2 ROWS ONLY
)
SELECT FISCAL_YEAR_VALUE
FROM T ORDER BY FISCAL_YEAR_VALUE
)
)
AND FISCAL_WEEK IN (SELECT *
FROM (WITH T AS (
SELECT DISTINCT FISCAL_WEEK, FISCAL_YEAR_VALUE
FROM TABLE_NAME
WHERE TRUNC(DATE_VALUE) <= TRUNC(TO_DATE('21-JAN-22'))--TEST DATE
ORDER BY FISCAL_YEAR_VALUE DESC, FISCAL_WEEK DESC
OFFSET 1 ROWS
FETCH NEXT 4 ROWS ONLY
)
SELECT FISCAL_WEEK
FROM T ORDER BY FISCAL_YEAR_VALUE, FISCAL_WEEK
)
)
GROUP BY FISCAL_YEAR_VALUE, FISCAL_WEEK
ORDER BY FISCAL_YEAR_VALUE, FISCAL_WEEK
Output of the code is:
FISCAL_YEAR_VALUE FISCAL_WEEK
2021 2
2021 1
2021 52
2021 53
2022 1
2022 2
As you can see, the last 2 weeks of year 2020 are not included. Please see example 2. How can I also include this exception in the code to make it dynamic? Any help would be greatly appreciated!
To find the values this year, you can use:
SELECT DISTINCT fiscal_year_value, fiscal_week
FROM table_name
WHERE date_value < TRUNC(SYSDATE, 'IW')
AND date_value >= TRUNC(SYSDATE, 'IW') - INTERVAL '28' DAY
To find the values from the previous year, you can find the maximum fiscal week from this year and subtract 1 from the year and then use that to find the upper bound of the date_value for last fiscal year and, given that can use a similar range for last year:
WITH this_year (fiscal_year_value, fiscal_week) AS (
SELECT fiscal_year_value, fiscal_week
FROM table_name
WHERE date_value < TRUNC(SYSDATE, 'IW')
AND date_value >= TRUNC(SYSDATE, 'IW') - INTERVAL '28' DAY
),
max_last_year (max_date_value) AS (
SELECT MAX(date_value) + INTERVAL '1' DAY
FROM table_name
WHERE (fiscal_year_value, fiscal_week) IN (
SELECT fiscal_year_value - 1, fiscal_week
FROM this_year
ORDER BY fiscal_year_value DESC, fiscal_week DESC
FETCH FIRST ROW ONLY
)
)
SELECT fiscal_year_value, fiscal_week
FROM this_year
UNION
SELECT t.fiscal_year_value, t.fiscal_week
FROM table_name t
INNER JOIN max_last_year m
ON ( t.date_value < m.max_date_value
AND t.date_value >= m.max_date_value - INTERVAL '28' DAY);
Which, for the sample data:
Create Table table_name(DATE_VALUE DATE, FISCAL_WEEK INT, FISCAL_YEAR_VALUE INT);
INSERT INTO table_name (date_value, fiscal_week, fiscal_year_value)
SELECT DATE '2019-12-30' + LEVEL - 1, CEIL(LEVEL/7), 2020
FROM DUAL
CONNECT BY LEVEL <= 7 * 52
UNION ALL
SELECT DATE '2020-12-28' + LEVEL - 1, CEIL(LEVEL/7), 2021
FROM DUAL
CONNECT BY LEVEL <= 7 * 53
UNION ALL
SELECT DATE '2022-01-03' + LEVEL - 1, CEIL(LEVEL/7), 2022
FROM DUAL
CONNECT BY LEVEL <= 7 * 52;
Outputs:
FISCAL_YEAR_VALUE
FISCAL_WEEK
2022
38
2022
39
2022
40
2022
41
2021
38
2021
39
2021
40
2021
41
And if today's date was 2022-01-01, would output:
FISCAL_YEAR_VALUE
FISCAL_WEEK
2021
52
2021
53
2022
1
2022
2
2020
51
2020
52
2021
1
2021
2
There may be a simpler method but without any knowledge of how you calculate a fiscal year that is not immediately possible.
fiddle

Repeat the day of the week for each time inside a string

I have a table with just one column and about 3000 rows that follows the same pattern. I want to include the days of the week at the beginning of the string for each TIME inside the same string in the row.
Original table :
DATA_TIME_COMBINATION
Monday 3 am HM, 5 am HC, 10 pm HX
Saturday AB 6 am, WE 5 pm
Sunday Friday AN 50 TU,FG 55 RE, DC 56 JJ
Tuesday 10 am, 5 am, 1 am
Wednesday 12 pm-9 pm- 1 am
Results needed :
DATA_TIME_COMBINATION
Monday 3 am HM, Monday 5 am HC, Monday 10 pm HX
Saturday AB 6 am, Saturday WE 5 pm
Sunday Friday AN 50 TU, Sunday Friday FG 55 RE, Sunday Friday DC 56 JJ
Tuesday 10 am, Tuesday 5 am, Tuesday 1 am
Wednesday 12 pm- Wednesday 9 pm- Wednesday 1 am
Thanks in advance!
seems you want replace the comma with a comma and the first word at beginning of the string
select replace(DATA_TIME_COMBINATION, ',',
concat(',', substr(DATA_TIME_COMBINATION,1,charindex(' ', DATA_TIME_COMBINATION)-1)))
from my_table
Once you know the character and days.
Then it'll become a simple replace.
One cross apply for the weekdays.
A second for a character in place.
SELECT
REPLACE(REPLACE([DATA_TIME_COMBINATION], chr, chr+' '+days+' '),' ',' ') as DATA_TIME_COMBINATION
FROM mytable AS t
CROSS APPLY (
SELECT STRING_AGG(value, ' ') days
FROM STRING_SPLIT(
LEFT([DATA_TIME_COMBINATION], PATINDEX('%[a-z] [0-9]%', [DATA_TIME_COMBINATION])), ' ') spl
WHERE value LIKE '%day'
) ca1
CROSS APPLY (
SELECT
chr = SUBSTRING([DATA_TIME_COMBINATION], PATINDEX('%[^A-Za-z0-9 ]%', [DATA_TIME_COMBINATION]), 1)
) ca2;
DATA_TIME_COMBINATION
Monday 3 am HM, Monday 5 am HC, Monday 10 pm HX
Saturday AB 6 am, Saturday WE 5 pm
Sunday Friday AN 50 TU, Sunday Friday FG 55 RE, Sunday Friday DC 56 JJ
Tuesday 10 am, Tuesday 5 am, Tuesday 1 am
Wednesday 12 pm- Wednesday 9 pm- Wednesday 1am
Test on db<>fiddle here

Create a table to have only working days excluding weekends and public holidays

I have 2 tables.
1st of them consists of working days for each month (year = 2020):
Month
Date from
Date to
January
01/01/2020
31/01/2020
February
01/02/2020
29/02/2020
March
01/03/2020
31/03/2020
2nd of them has a dates with public holidays for 2020 with the following format:
Date
Week day
Code
Working hours
01/01/2020
Wednesday
Holiday
0
08/03/2020
Sunday
Holiday
0
01/09/2020
Tuesday
Holiday
0
24/12/2020
Thursday
Holiday
0
I would like to create 1 table (with the format of 2nd table) which has data only working days excluding public holidays from 2nd table and weekends from calendar for 2020.
Thank you in advance for your help.
Regards,
You can create the table using:
CREATE TABLE working_days (
day DATE PRIMARY KEY,
week_day VARCHAR2(9)
GENERATED ALWAYS AS (CAST(RTRIM(TO_CHAR(day, 'FMDay')) AS VARCHAR2(9))),
code VARCHAR2(20),
working_hours NUMBER(4,2)
);
Then insert data using:
INSERT INTO working_days (day, code, working_hours)
WITH days (dt, date_to) AS (
SELECT TRUNC(date_from),
date_to
FROM working_day_ranges
UNION ALL
SELECT dt + INTERVAL '1' DAY,
date_to
FROM days
WHERE dt + INTERVAL '1' DAY <= date_to
)
SELECT dt, 'Working Day', 23
FROM days d
WHERE NOT EXISTS ( -- Not a holiday
SELECT 1
FROM holidays h
WHERE d.dt = h.dt
)
AND dt - TRUNC(dt, 'IW') < 5 -- Not a Saturday or Sunday;
ORDER BY dt;
(Alter the expected working hours, etc. as suits you.)
Which, assuming your tables:
CREATE TABLE working_day_ranges (Date_from, Date_to) AS
SELECT DATE '2020-01-01', DATE '2020-01-31' FROM DUAL UNION ALL
SELECT DATE '2020-02-01', DATE '2020-02-29' FROM DUAL UNION ALL
SELECT DATE '2020-03-01', DATE '2020-03-31' FROM DUAL;
ALTER TABLE working_day_ranges
ADD month VARCHAR2(8)
GENERATED ALWAYS AS (CAST(RTRIM(TO_CHAR(date_from, 'FMMonth')) AS VARCHAR2(8)));
CREATE TABLE holidays (dt, Code, Working_hours) AS
SELECT DATE '2020-01-01', 'Holiday', 0 FROM DUAL UNION ALL
SELECT DATE '2020-03-08', 'Holiday', 0 FROM DUAL UNION ALL
SELECT DATE '2020-09-01', 'Holiday', 0 FROM DUAL UNION ALL
SELECT DATE '2020-12-24', 'Holiday', 0 FROM DUAL;
ALTER TABLE holidays
ADD week_day VARCHAR2(9)
GENERATED ALWAYS AS (CAST(RTRIM(TO_CHAR(dt, 'FMDay')) AS VARCHAR2(9)));
Then:
SELECT * FROM working_days;
Outputs:
DAY
WEEK_DAY
CODE
WORKING_HOURS
02-JAN-20
Thursday
Working Day
23
03-JAN-20
Friday
Working Day
23
06-JAN-20
Monday
Working Day
23
07-JAN-20
Tuesday
Working Day
23
08-JAN-20
Wednesday
Working Day
23
09-JAN-20
Thursday
Working Day
23
10-JAN-20
Friday
Working Day
23
13-JAN-20
Monday
Working Day
23
14-JAN-20
Tuesday
Working Day
23
15-JAN-20
Wednesday
Working Day
23
16-JAN-20
Thursday
Working Day
23
17-JAN-20
Friday
Working Day
23
20-JAN-20
Monday
Working Day
23
21-JAN-20
Tuesday
Working Day
23
22-JAN-20
Wednesday
Working Day
23
23-JAN-20
Thursday
Working Day
23
24-JAN-20
Friday
Working Day
23
27-JAN-20
Monday
Working Day
23
28-JAN-20
Tuesday
Working Day
23
29-JAN-20
Wednesday
Working Day
23
30-JAN-20
Thursday
Working Day
23
31-JAN-20
Friday
Working Day
23
03-FEB-20
Monday
Working Day
23
04-FEB-20
Tuesday
Working Day
23
05-FEB-20
Wednesday
Working Day
23
06-FEB-20
Thursday
Working Day
23
07-FEB-20
Friday
Working Day
23
10-FEB-20
Monday
Working Day
23
11-FEB-20
Tuesday
Working Day
23
12-FEB-20
Wednesday
Working Day
23
13-FEB-20
Thursday
Working Day
23
14-FEB-20
Friday
Working Day
23
17-FEB-20
Monday
Working Day
23
18-FEB-20
Tuesday
Working Day
23
19-FEB-20
Wednesday
Working Day
23
20-FEB-20
Thursday
Working Day
23
21-FEB-20
Friday
Working Day
23
24-FEB-20
Monday
Working Day
23
25-FEB-20
Tuesday
Working Day
23
26-FEB-20
Wednesday
Working Day
23
27-FEB-20
Thursday
Working Day
23
28-FEB-20
Friday
Working Day
23
02-MAR-20
Monday
Working Day
23
03-MAR-20
Tuesday
Working Day
23
04-MAR-20
Wednesday
Working Day
23
05-MAR-20
Thursday
Working Day
23
06-MAR-20
Friday
Working Day
23
09-MAR-20
Monday
Working Day
23
10-MAR-20
Tuesday
Working Day
23
11-MAR-20
Wednesday
Working Day
23
12-MAR-20
Thursday
Working Day
23
13-MAR-20
Friday
Working Day
23
16-MAR-20
Monday
Working Day
23
17-MAR-20
Tuesday
Working Day
23
18-MAR-20
Wednesday
Working Day
23
19-MAR-20
Thursday
Working Day
23
20-MAR-20
Friday
Working Day
23
23-MAR-20
Monday
Working Day
23
24-MAR-20
Tuesday
Working Day
23
25-MAR-20
Wednesday
Working Day
23
26-MAR-20
Thursday
Working Day
23
27-MAR-20
Friday
Working Day
23
30-MAR-20
Monday
Working Day
23
31-MAR-20
Tuesday
Working Day
23
db<>fiddle here

How to get last 90 days monday to sunday date?

How to get last 90 days monday to sunday date.
S.no Start_dt End_dt week
1 18-Jul-16 24-Jul-16 Week1
2 25-Jul-16 31-Jul-16 Week2
3 1-Aug-16 7-Aug-16 Week3
4 8-Aug-16 14-Aug-16 Week4
5 15-Aug-16 21-Aug-16 Week5
6 22-Aug-16 28-Aug-16 Week6
7 29-Aug-16 4-Sep-16 Week7
8 5-Sep-16 11-Sep-16 Week8
9 12-Sep-16 18-Sep-16 Week9
10 19-Sep-16 25-Sep-16 Week10
11 26-Sep-16 2-Oct-16 Week11
12 3-Oct-16 9-Oct-16 Week12
13 10-Oct-16 16-Oct-16 Week13
We need to use sysdate as input.
I am trying below query it return current week monday ,sunday date
SELECT TRUNC(sysdate, 'D') +1 startofweek, TRUNC(sysdate, 'D') + 7
endofweek FROM dual;
select trunc(sysdate-(13-rownum)*7, 'iw') start_dt, trunc(sysdate-(12-rownum)*7, 'iw')-1 end_dt, 'week'||rownum week
from dual
connect by rownum<=90/7+1