How to do rolling weeks based on date? - sql-server

I'm currently at a data analyst student job following an internship and I have do to reports based on the ticketing tool of the company, so, I'm using a pre-calculated table (the administrator have made pre-calculated tables based on his querys).
I have week table with all I need and I have to do a rolling 26 week report.
Because it is calculated that are historized and I don't have creation_date or end_date column.
I can't manage to do this can you help me with this ?
Actually, as a rolling query, if I have 18 weeks for 2021 I will need the 8 weeks last weeks of 2020.
I have this columns : Closed, Week, Month, Backlog... and I need it just for Closed.
I've tried this :
SELECT SUM(CLOSED), WEEK, MONTh, YEAR
FROM E_GROUPE_INTERVENANT_SEMAINE_HISTORY
WHERE MONTH >= Month(getdate())-6
AND YEAR <= YEAR(getdate())
EDIT : The weeks range values 1 trough 53 or 52 it depends on the year, the weeks are weeks of month, I've tried this
SELECT SUM(CLOSED), WEEK, MONTH, YEAR
FROM E_GROUPE_INTERVENANT_SEMAINE_HISTORY
WHERE
YEAR(DATEADD(WEEK, -26, GETDATE())) = YEAR(GETDATE()) - 1
AND
YEAR = YEAR(GETDATE())
AND
MONTH <= Month(DATEADD(WEEK, -26, GETDATE()))
)
group by WEEK, MONTH, YEAR
order by WEEK, YEAR
But I'm only getting week for the current year the previous year doesn't show.
I wonder if it's even possible to have the last year because without the pre-calculated tables I could get the last year with my querys but they want me to use this table.
Thank you for your help.

I don't see what your week value is but this will get you close:
SELECT SUM(CLOSED), WEEK, MONTH, YEAR
FROM E_GROUPE_INTERVENANT_SEMAINE_HISTORY
WHERE (--CURRENT YEAR WHEN YEAR IS NOT CROSSED
YEAR(DATEADD(WEEK, -18, GETDATE())) = YEAR(GETDATE())
AND
YEAR = YEAR(GETDATE())
AND
MONTH >= Month(DATEADD(WEEK, -18, GETDATE()))
)
OR
( --LAST MONTHS OF LAST YEAR WHEN YEAR IS SPANNED
MONTH >= Month(DATEADD(WEEK, -18, GETDATE()))
AND
YEAR = YEAR(DATEADD(WEEK, -18, GETDATE()))
)
OR
(--ALL MONTHS FOR CURRENT YEAR WHEN YEAR IS CROSSED
YEAR(DATEADD(WEEK, -18, GETDATE())) = YEAR(GETDATE()) - 1
AND
YEAR = YEAR(GETDATE())
AND
MONTH <= Month(DATEADD(WEEK, -18, GETDATE()))
)

Related

How to find the past 4 weeks of the same weekday value starting today

I am trying to select records from today and the same day of each week for the last 4 weeks.
Today (Tuesday)
Last Tuesday
The Tuesday before that
The Tuesday before that
I need this to be tied to current date because I am going to run this query every day so I don't want to use a between or something where I manually specify the date range.
Everything I have found or tried so far has pulled the last month of data but not the last 4 weeks of the same weekday.
select *
from table
where thedatecolumn >= DATEADD(mm, -1, GETDATE())
This works but pulls everything from the last month.
If today's date is 7/10/2019 I need
Data from 7/10/2019
Data from 7/3/2019
Data from 6/26/2019
Data from 6/19/2019
Every day I will run this query, so I need it to be dynamic based on the current date.
I believe you want to look back 21 days and then filter those dates that have the same day of week:
select * from table
where thedatecolumn >= DATEADD(DAY, -21, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, thedatecolumn) = DATEPART(WEEKDAY, GETDATE())
You Can try using a recursive cte which starts today and repeatedly substracts 7 days - so you ensure you always land on the same weekday. Following an example:
WITH cteFromToday AS(
SELECT 0 AS WeeksBack, GETDATE() AS MyDate
UNION ALL
SELECT WeeksBack + 1 AS WeeksBack, DATEADD(d, -7, MyDate) AS MyDate
FROM cteFromToday
)
SELECT TOP 5 *
FROM cteFromToday
OPTION ( MaxRecursion 0 );
This is quite simple. Substitute CURRENT_TIMESTAMP here for any given date.
SELECT CONVERT(DATE,CURRENT_TIMESTAMP) AS Today,
DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AS LastWeek ,
DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AS TwoWeeksAgo,
DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AS ThreeWeeksAgo
SO, if you want to get data for a set of ranges for one entire day with those dates:
SELECT something
WHERE
datetimecolumn >= CONVERT(DATE,CURRENT_TIMESTAMP) AND datetimecolumn < DATEADD(DAY,1, CONVERT(DATE,CURRENT_TIMESTAMP)) -- Todays range,
OR datetimecolumn >= DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)))-- LastWeek ,
OR datetimecolumn >= DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)))-- TwoWeeksAgo,
OR datetimecolumn >= DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1, DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP))) -- ThreeWeeksAgo

Replicate SQL Server DATEPART(wk, ...) function in Delphi

Delphi's WeekOfTheYear function uses the ISO 8601 methodology where the week starts on a Monday, and the first week of a year is defined as the first week with four or more days in that year.
To get the week of the year in Microsoft SQL Server, you use the DATEPART(wk, ...) function, but this uses a different mechanism, in that the default for U.S. English starts the week on Sunday, and that the 2nd week of the year is the first Sunday of the year, unless that Sunday is the 1st of January, then the 2nd week starts on the 2nd Sunday of the year, as can be seen if you run this example:
SELECT '2010-1-3', DATEPART(wk, '2010-1-3'), DATENAME(dw, '2010-1-3')
SELECT '2011-1-2', DATEPART(wk, '2011-1-2'), DATENAME(dw, '2011-1-2')
SELECT '2012-1-1', DATEPART(wk, '2012-1-1'), DATENAME(dw, '2012-1-1')
SELECT '2013-1-6', DATEPART(wk, '2013-1-6'), DATENAME(dw, '2013-1-6')
SELECT '2014-1-5', DATEPART(wk, '2014-1-5'), DATENAME(dw, '2014-1-5')
SELECT '2015-1-4', DATEPART(wk, '2015-1-4'), DATENAME(dw, '2015-1-4')
SELECT '2016-1-3', DATEPART(wk, '2016-1-3'), DATENAME(dw, '2016-1-3')
SELECT '2017-1-1', DATEPART(wk, '2017-1-1'), DATENAME(dw, '2017-1-1')
SELECT '2018-1-7', DATEPART(wk, '2018-1-7'), DATENAME(dw, '2018-1-7')
SELECT '2019-1-6', DATEPART(wk, '2019-1-6'), DATENAME(dw, '2019-1-6')
SELECT '2020-1-5', DATEPART(wk, '2020-1-5'), DATENAME(dw, '2020-1-5')
The results from above show every Sunday being the 2nd week of the year, except for the 2 that are the 1st January, which show the 1st week of the year.
I looked at the answer for the question below, that seemed to indicate it would return the week of the year depending on what day the week starts,
Delphi week number function based on system start of week
but that is also based on using the Delphi functions, and does not return the same results as SQL Server.
What SQL Server currently shows for the dates 1st January 2018 to 8th January 2018 is:
1/1/2018 = 1
2/1/2018 = 1
3/1/2018 = 1
4/1/2018 = 1
5/1/2018 = 1
6/1/2018 = 1
7/1/2018 = 2
8/1/2018 = 2
Delphi does have a DayOfWeek function that uses Sunday as the first day of the week, compared to the DayofTheWeek function which uses Monday, but I just can't seem to work out the logic that is needed to get the same results as SQL Server. There has to at least be a condition in there for dealing with Sunday 1st January being week 1, but for the first other Sundays being week 2.
Does anyone have any Delphi source code that returns the week of the year exactly as SQL Server does when using U.S. English default of DATEFIRST 7?
The code is deceptively simple, but the logic of it is a little difficult. The rule about the first Sunday means that, in all cases the first Saturday is in week 1. So the idea is that we go to the next Saturday and count the number of Saturdays from the start of the year.
function SQLWeekOfYear(const pDate: TDate): integer;
var
iYear, iMonth, iDay : word;
iDOW : integer;
iDays : integer;
begin
// this is based on First Sunday in year being in week 2
// unless it is the first of Jan, which is equivalent of saying that the
// first saturday is always in week 1.
//
// This means that we count the number of saturdays prior to this date and add one,
// which is equivalent to finding the next saturday
DecodeDate( pDate, iYear, iMonth, iDay );
iDOW := DayOfWeek( pDate );
// Find how many days so far since 1st jan
iDays := Trunc(pDate - EncodeDate( iYear, 1, 1 )) + 1;
// now adjust for day of week to get to next saturday
iDays := iDays + (7-iDOW);
// add 6 and divide by 7 to find actual number saturdays
Result := (iDays + 6) div 7;
end;

Decision based on what day of the week a date falls on

For any given date I need to determine what day of the week it is.
I already know how to get the day of the week with this DATENAME(dw,MyDate.Field)and the number of the day with this DATEPART(dw,MyDate.Field).
Once I've got the day of the week if it is before Wednesday I want to return that Wednesday's date.
If the day of the week is Wednesday or after then I want to return next Wednesdays date.
Monday is day 1 in my system.
Use DATEPART() to determine day of the week.
Use CASE() for the different cases.
Calculate the day delta. Hint: It's either 3-dw or 7+3-dw.
Use DATEADD() to get from the current day (returned by DATEPART) to Wednesday or Wednesday of next week.
the easiest way, without any calculating:
set datefirst 1;
with dates as (
select CAST('20170906' as datetime) d
union all
select DATEADD(day, 1, dates.d)
from dates
where DATEADD(day, 1, dates.d) <= '20170930'
)
select dates.d, DATEADD(day, v.valueToAdd, dates.d) nextWed
from dates
join (values(1,2),(2,1),(3,7),(4,6),(5,5),(6,4),(7,3))v(dayOfWeek,valueToAdd) on v.dayOfWeek = DATEPART(weekday, dates.d)
order by 1

MSSQL order by previous 7 days

I run this query in MSSQL to get the items, grouping by the last 7 days of the week:
SELECT COUNT(Date_Entered), DATENAME(WEEKDAY, Date_Entered)
FROM my_table
WHERE Board_Name = 'Board'
AND DATEDIFF(DAY,Date_Entered,GETDATE()) <= 7
GROUP BY DATENAME(WEEKDAY, Date_Entered)
In the result, days of the week are sorted in alphabetical order: Friday > Monday > Saturday > Sunday > Thursday > Tuesday > Wednesday
How do I sort by the normal/correct/common sense order, starting with the weekday of 7 days ago and ending with yesterday?
Ordering by MAX(Date_Entered) should work too:
SELECT
COUNT(Date_Entered),
DATENAME(WEEKDAY, Date_Entered)
FROM my_table
WHERE Board_Name = 'Board' AND DATEDIFF(DAY,Date_Entered,GETDATE()) <= 7
GROUP BY DATENAME(WEEKDAY, Date_Entered)
ORDER BY MAX(Date_Entered);
Normally you would want to order by the date ascending, but since you use an aggregate function you would need to group by the date which would ruin it, but since the max(date) in every group is the date you can do max(date) to order.
DATEPART is your friend, try it like this:
SELECT COUNT(Date_Entered), DATENAME(WEEKDAY, Date_Entered),DATEPART(WEEKDAY,Date_Entered)
FROM my_table
WHERE Board_Name = 'Board'
AND DATEDIFF(DAY,Date_Entered,GETDATE()) <= 7
GROUP BY DATEPART(WEEKDAY,Date_Entered),DATENAME(WEEKDAY, Date_Entered)
ORDER BY DATEPART(WEEKDAY,Date_Entered)
If you can't count on data being available for every week then you'd need to do something more based on date calculations. Off the top of my head I think this will be more reliable:
ORDER BY (DATEDIFF(dd, MAX(Date_Entered), CURRENT_TIMESTAMP) + 77777) % 7
EDIT: I wrote that not realizing that the data was already limited to a single week. I thought the intention was to group in buckets by day of week for a longer range of dates.
I'll also comment that to me it is more natural to do the grouping on cast(Date_Entered as date) rather than on a string value and I wouldn't be surprised if it's a more efficient query.

SQL Server : get day of month from Year Month WeekOfMonth

I have a complicated calendar report coming from a SQL query where I have the year, month and WeekNumOfMonth (meaning the week number from the beginning of the month).
I need a function to return the DayOfMonth (ie: values of between 1-28,29,30 or 31 depending on the month) given Year, month and WeekNumOfMonth.
I have seen functions that do this given WeekNum from beginning of year but I only have WeekNum of the given month. I just can't seem to give the datePart and dateAdd functions right. Any help would be appreciated.
Note : Combination of Year ,Month ,Week Number will not give you the
day name because a week contain more than one day so how can you find
which day is it ? it is not possible
example : year 2015 month 06 week number 1
then it has a combination of
1 monday
2 tuesday
3 wednesday
4 thursday
5 friday
6 saturday
then with these results how can you predit the exact day ??
Else need some conditions or restrictions
If you have Year, Month , and date then you can find the day name using the below query it will give the start and end date of the week then you can take the dates from start date and end with end date
SELECT (
DATENAME(dw,
CAST(DATEPART(m, GETDATE()) AS VARCHAR)
+ '/'
+ CAST(DATEPART(d, '2015-06-23') AS VARCHAR)
+ '/'
+ CAST(DATEPART(yy, getdate()) AS VARCHAR))
)
Update
If you need all days between the current week then use the following query
DECLARE
#Year INT,
#Week INT,
#FirstDayOfYear DATETIME,
#FirstMondayOfYear DATETIME,
#StartDate DATETIME,
#EndDate DATETIME
SET #Year = 2015
SET #Week = 24// week number is based on year and it is not based on month
-- Get the first day of the provided year.
SET #FirstDayOfYear = CAST('1/1/' + CAST(#YEAR AS VARCHAR) AS DATETIME)
-- Get the first monday of the year, then add the number of weeks.
SET #FirstMondayOfYear = DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, #FirstDayOfYear), #FirstDayOfYear)), 0)
SET #StartDate = DATEADD(WEEK, #Week - 1, #FirstMondayOfYear)
-- Set the end date to one week past the start date.
SET #EndDate = DATEADD(WEEK, 1, #StartDate)
SELECT #StartDate AS StartDate, DATEADD(SECOND, -1, #EndDate) AS EndDate
Update
if do not have the year week number then use the below query
DATEPART(WEEK,'2015-06-01')
The above query is one example
In the query you have two values that is Year and Month
you need only the third value that means date
as a technique you can give 01 as the date then it will give the
starting week number your selected month
here it will result 23 so you got the idea in 2015 - month 06 starts with week number 23 so then you can easily do your stuff
Idea : if your week number is 1 then take 23 as week if it is 2 then 24 like wise..

Resources