Calculate Week Numbers based on the initial given date to end date - sql

I have below scenario that Business want to calculate Week Number based on Given Start Date to End Date.
For Ex: Start Date = 8/24/2020 End Date = 12/31/2020 ( These Start date & end date are not constant they may change from year to year )
Expected Output below:
[Date 1 Date 2 Week Number
8/24/2020 8/30/2020 week1
8/31/2020 9/6/2020 week2
9/7/2020 9/14/2020 week3
9/15/2020 9/21/2020 week4
9/22/2020 9/28/2020 week5
9/29/2020 10/5/2020 week6
10/6/2020 10/12/2020 week7
10/13/2020 10/19/2020 week8
10/20/2020 10/26/2020 week9
10/27/2020 11/02/2020 week10
11/03/2020 11/09/2020 week11
11/10/2020 11/16/2020 week12
11/17/2020 11/23/2020 week13
11/24/2020 11/30/2020 week14
I need Oracle Query to calculate Week Number(s) like above .. Based on Start date for 7 days then week number will be calcuated.. But remember that crossing months some month have 30 days and some month 31 days etc.. How to calculate ? Appreciate your help!!

Seems your looking for custom week definition rather that built-ins. But not overly difficult. The first thing is to convert from strings to dates (if columns actually coming off table this conversion is not required), and from there let Oracle do all the calculations as you can apply arithmetic operations to dates, except adding 2 dates. Oracle will automatically handle differing number of days per month correctly.
Two methods for this request:
Use a recursive CTE (with)
with dates(start_date,end_date) as
( select date '2020-08-24' start_date
, date '2020-12-31' end_date
from dual
)
, weeks (wk, wk_start, wk_end, e_date) as
( select 1, start_date, start_date+6 ld, end_date from dates
union all
select wk+1, wk_end+1, wk_end+7, e_date
from weeks
where wk_end<e_date
)
select wk, wk_start, wk_end from weeks;
Use Oracle connect by
with dates(start_date,end_date) as
( select date '2020-08-24' start_date
, date '2020-12-31' end_date
from dual
)
select level wk
, start_date+7*(level-1) wk_start
, start_date+6+7*(level-1)
from dates
connect by level <= ceil( (end_date-start_date)/7.0);
Depend on how strict you need to be with the end date specified you may need to adjust the last row returned. Both queries do not make adjust for that. They just ensure no week begins after that date. But the last week contains the full 7 days, which may end after the specified end date.

If your date datatype is varchar then first convert it to date and then convert it back to varchar.
convert date to to_char(to_date('8/24/2020','MM/DD/YYYY'),'WW')
If you to keep week datatype as a number then you can do something like this
to_number(to_char(to_date('8/24/2020','MM/DD/YYYY'),'WW'))
Few options according to your need.
WW Week of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
W Week of month (1-5) where week 1 starts on the first day of the month and ends on the seventh.
IW Week of year (1-52 or 1-53) based on the ISO standard.

Related

Data of last 6 quarter including current quarter

How to get data of last 6 quarter in Oracle including current quarter. I mean if I run the query today so data between 01-JAN-2018 to 30-JUN-2019 should come in the query.
You could do something like this:
SELECT
*
FROM
DUAL
WHERE
DATE_FIELD >= (SYSDATE - (30*(3*6)))
What this query is doing is taking the current date (SYSDATE), and grabbing all values from the previous 6 quarters. The rationale is:
30 = days in a month | 3 = months in a quarter | 6 = quarters specified by OP
You can use add_months and trunc functions for date value with Q(quarter) argument
select t.*
from tab t
where insert_date between
trunc(add_months(sysdate,-3*5),'Q')
and trunc(add_months(sysdate,3),'Q')-1;
Demo for verification
for the starting date, -3*(6-1) = -3*5 considered, starting from 5 quarter back to be able to count 6 quarter including the current quarter. 3 is
obvious as being the number of months in each quarter.

Oracle: Date Range

I have the below Query & table:
Problem:
I'm trying to capture IDs that were Reassigned for that month.
For example the month of August total number of ReAssigned would be 1 and not 3
How can this be captured?
I need to count Per Month, for example. How mamy ids were reassigned for the month of August, Sept, ect.
So, the Most_Rent_Assigment date needs to fall within the month
Aug: 8/1-8/31
Sept: 9/1-9/30
Then count to capture how many ids were reassigned in that month
,CASE WHEN
H.FIRST_ASSGN_DT IS NULL THEN 'UnAssigned'
WHEN h.TOTAL_NUMBER_OF_REASSIGNMENTS = 0 OR h.TOTAL_NUMBER_OF_REASSIGNMENTS IS NULL
AND h.FIRST_ASSGN_DT IS NOT NULL THEN 'NewlyAssigned'
ELSE 'ReAssigned'
END ASSIGNED_STATUS
Table:
ID Total_Number_Reassignment Most_Recent_Assignment StartDate *Assigned Status
1 2 11/01/2016 08/1/2017 ReAssigned
2 3 08/02/2017 08/01/2017 ReAssigned
3 0 08/15/2017 NewlyAssigned
4 5 12/01/2016 09/01/2017 ReAssigned
Date ranges in Oracle can be accomplished by using BETWEEN.
If the columns are type DATE then you can just do: WHERE TRUNC(Most_Recent_Assignment) BETWEEN TO_DATE('2017-08-01') AND TO_DATE('2017-08-31')
Note: the TRUNC will truncate the date to midnight, so you don't lose results based on time of day.
Edit:
OP clarified his question.
To count occurrences for a particular month, you can group by month.
SELECT
TO_CHAR('Most_Recent_Assignment', 'mm'),
COUNT(TO_CHAR('Most_Recent_Assignment', 'mm'))
FROM TABLE
WHERE ...
GROUP BY TO_CHAR('Most_Recent_Assignment', 'mm')
TO_CHAR parses a date as a string. mm will return a 2-digit month. You can replace it with Month to get the name of the month.
The group will put all months together.

local week of the year in postgresql

I have to generate year wise, weekly reports for some data. Now When I aggregate date on week number, and week number is calculated from extract from creation date.
Now the problem is these both queries return week number 52.
SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-01-01');
SELECT EXTRACT(WEEK FROM TIMESTAMP '2006-12-31');
First query return 52 (52nd week of 2005) and 2nd query return 52 (52nd week of year 2006). thats documented behavior.
But I want to Calculate local week number, and results for first query should be 1 and other query would return 53.
You can't do this with the exctract() function, it only supports ISO weeks.
But the to_char() function has an option for this:
SELECT to_char(DATE '2006-01-01', 'WW')::int` --> 1
SELECT to_char(DATE '2006-12-31', 'WW')::int` --> 53
For date 2006-01-01 end week is start in 2005 year, that same problem is 1999 year.
Clausule EXTRACT(WEEK getting year where week is started not ending.
You can use this code:
SELECT floor(EXTRACT(doy FROM TIMESTAMP '2006-01-01')/7 + 1);
SELECT floor(EXTRACT(doy FROM TIMESTAMP '2006-12-31')/7 + 1);

How to subtract 13 weeks from a date in PL SQL?

I have a date in sql which will always fall on a Monday and I'm subtracting 13 weeks to get a weekly report. I am trying to get the same 13 week report but for last year's figures as well.
At the moment, I'm using the following:
calendar_date >= TRUNC(sysdate) - 91
which is working fine.
I need the same for last year.
However, when I split this into calendar weeks, there will also be a partially complete week as it will include 1 or 2 days from the previous week. I need only whole weeks.
e.g. the dates that will be returned for last year will be 14-Feb-2015 to 16-May-2015. I need it to start on the Monday and be 16-Feb-2015. This will change each week as I am only interested in complete weeks...
I would do this:
Get the date by substracting 91 days as you're already doing.
Get the number of the day of the week with TO_CHAR(DATE,'d')
Add the number of days until the next monday to the date.
Something like this:
SELECT TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/YYYY')-91 + MOD(7 - TO_NUMBER(TO_CHAR(TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/RRRR')-91,'d'))+1,7) d
FROM dual
next_day - returns date of first weekday named by char.
with dates as (select to_date('16/05/2015','DD/MM/YYYY') d from dual)
select
trunc(next_day( trunc(d-91) - interval '1' second,'MONDAY'))
from dates;
I want to get next monday from calculated date. In situation when calculated date is monday i have to move back to previous week ( -1 second).

day of the week in the week numbering

in oracle there is a possibility to change starting day of the week.
In US first day is SUN, and in EU - MON
This change works by changing nls_territory
However if I consider day of the week and week numbering at once, I have following situation:
day week_number
7 9 <- here it should be still week 8
1 9
2 9
3 9
4 9
5 9
6 9
7 10 <- here it should still be week 9
Do you have any idea which nls should could affect this start_day of the week?
Similar post
Get First Day Of Week From Week Number
Oracle has two date formats which give us the Week Number.
'WW' starts from the first of January and increments every seven days. As 01-JAN-2013 was a Tuesday that means the Week Number increments on a Tuesday. I guess this is the version you're using at the moment.
But there is also the 'IW' format, which is the ISO standard. In this version, the week number starts from the Monday of the week where the first of January falls. This has the peculiar side-effect of making 31-DEC-2012 the first date of Week 1 on 2013, but it does mean the week number always increments on day 1 of the week.
Find out more.
Not sure I understand your question and I see no connection between day# and week# in your example, sorry... Maybe this will help you to get ISO week. This builds annual week table. You may add 'WW' format to the query and compare dates, weeks in diff. NLS settings:
-- ISO_WK# --
SELECT mydate
, TRUNC(mydate, 'w') wk_starts
, TRUNC(mydate, 'w') + 7 - 1/86400 wk_ends
, TO_NUMBER (TO_CHAR (mydate, 'IW')) ISO_wk#
FROM
(
SELECT TRUNC(SYSDATE, 'YEAR')-1 + LEVEL AS mydate
FROM dual
CONNECT BY LEVEL <=
(
SELECT TRUNC(SYSDATE, 'YEAR')-TRUNC(ADD_MONTHS (SYSDATE, -12), 'YEAR') "Num of Days"
FROM dual
)
)
/