Identify month's week number using SQL - sql

I would need to find month's week number. I know the ways to find week number for year but not a month's.
Example:
Sep 2019
Week 1 – 1st to 1st
Week 2 – 2nd to 8th
Week 3 – 9th to 15th
Week 4 – 16th to 22nd
Week 5 – 23rd to 29th
Week 6 – 30th to 30th
I tried finding one using below logic but it's taking 1st of Sep 2019 as 4th week. But I need the value as 1 here
declare #date datetime = '2019-09-01'
select datepart(day, datediff(day, 0, #date)/7*7)/7, datepart(day, datediff(day, 0, #date)/7 * 7)/7 + 1
Appreciate your help with this.

Try with this
DECLARE #MyDate DATETIME
SET #MyDate = '2019-09-01'
SELECT DATEPART(WEEK, #MyDate) - DATEPART(WEEK, DATEADD(MM, DATEDIFF(MM,0,#MyDate), 0))+ 1 AS NoOfWeeks

Related

SQL Server compare amount with date range

all, I need help about my works
I have to compare data between current month and previous month and also with date and day range. I have amount in current month (December) between 1st December and 3rd December. 1st December is on Wednesday, 2nd December is on Thursday, and 3rd December is on Friday. 1st December until 3rd December is the first week on December. The previous month, first week on November, Wednesday until Friday is on 3rd, 4th and 5th November.
How can I perform this in SQL Server?
What I've tried is looked like this:
select *
from (
-- Current Month
SELECT Businessday, Amount, datename(dw,BusinessDay) AS DaysName,
DATEDIFF(WEEK, DATEADD(MONTH, DATEDIFF(MONTH, 0, BusinessDay), 0), BusinessDay) +1 AS WeekNumber
FROM TableTransaction
WHERE Businessday BETWEEN '2021-12-01 00:00:00.000' AND '2021-12-03 00:00:00.000'
) x left join (
-- Previous Month
SELECT Businessday, Amount, datename(dw,BusinessDay) AS DaysName,
DATEDIFF(WEEK, DATEADD(MONTH, DATEDIFF(MONTH, 0, BusinessDay), 0), BusinessDay) +1 AS WeekNumber
FROM TableTransaction
WHERE Businessday BETWEEN '2021-11-01 00:00:00.000' AND '2021-11-30 00:00:00.000'
) y on x.DaysName = y.DaysName AND x.WeekNumber = y.WeekNumber
Another thought is, How if range date which I chose is 23th December until 30th December which is Thursday in fourth week, the previous month is (Thursday in fourth week) the range is until first week of December, how can I perform this?
Your answer will be so helpful.

Is there a way to set relative start and end dates in SQL for last 4 complete months and current month to date?

If applied to today, I want to return values for 1/10/19 through 25/02/20.
I am using the below currently, but wish to replace it with something that gives me 4 complete months and the current partial month
where DATEDIFF (day,[SubOrderCompletionDate],GETDATE()) between 0 and 180
Thanks
If you want complete months, just change this to:
where DATEDIFF(month, SubOrderCompletionDate, GETDATE()) between 0 and 3
DATEDIFF() counts the number of boundaries between two dates. So, all days within a given calendar month return the same value.
I've taken your statement literally, and therefore assumed that if today was 29 February 2020 you would want 1 November 2019 to 29 February 2020, not 1 October 2019 to 29 Feburary 2020:
SELECT * --This should be a column list, not *
FROM dbo.YourTable YT
WHERE YT.SubOrderCompletionDate >= CASE WHEN EOMONTH(GETDATE()) = CONVERT(date,GETDATE()) THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 3,0) ELSE DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 4,0) END
AND YT.SubOrderCompletionDate <= GETDATE()
If that isn't the case, you just need DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 4,0), which will give you 5 months worth of data.

SQL - pick current date from machine and compare with previous week

For the below query
Sum(CASE WHEN dbo.sales.date BETWEEN '2016-07-17' AND '2016-07-23' THEN dbo.sales.sellinc END) AS ActualSales
Instead of hard coding the date. I would like to pick current date from machine and compare
Sum(CASE WHEN dbo.sales.date BETWEEN '**previous week (31 week 2016)**' AND '**Last year same week (31 week 2015)**' THEN dbo.sales.sellinc END) AS ActualSales
Week start from Sunday and ends Saturday. Any help please?
I think this snippet might help you to get a range of one year from the previous week to last year.
Sum(CASE
WHEN dbo.sales.date
BETWEEN DATEADD(YEAR, -1, DATEADD(WEEK, -1, GETDATE())) AND
DATEADD(WEEK, -1, GETDATE()) THEN dbo.sales.sellinc END) AS ActualSales
You can also modify the logic if you want to consider Friday as an exception.
In that case, you have to use DATEPART(WEEKDAY, GETDATE()) function to get the week day which returns 1 for Sunday and 7 for Saturday. It would be prettier if you move the date generation logic to a variable and then use it to select your data.
Others have already noted that your method of week numbering is going to impact your solution. Here's one that just looks for the Sunday of the current week and then subtracts 52 weeks. (You could also just deduct 364 days in the previous step and use dateadd only once.) So the correspondence with the previous year's week is essentially the nearest calendar date falling on Sunday that year.
with dates as (
select
dateadd(week, -52,
dateadd(day,
1 - datepart(weekday, getdate()), /* Sunday of current week */
cast(getdate() as date)
)
) as WeekStartY-1,
dateadd(day, 1 - datepart(weekday, cast(getdate() as date)) as WeekStartY-0
)
select
sum(case when cast(s."date" as date)
between d.WeekStartY-0 and dateadd(day, 6, WeekStartY-0) then s.sellinc end
) as ActualSalesY-0,
sum(case when cast(s."date" as date)
between d.WeekStartY-1 and dateadd(day, 6, WeekStartY-1) then s.sellinc end
) as ActualSalesY-1,
from dbo.Sales s cross apply dates d;
This can occasionally produce an oddity where the weeks both start in the same year. It happens when the year ends on Sunday, or Monday in leap years, as with 2012. So Y-1 for December 30, 2012 was January 1, 2012. But consider that most of the days for that week actually fall in 2013 and the correspondence makes sense from that perspective.
You can try using DATEADD:
SUM(CASE WHEN dbo.sales.date BETWEEN DATEADD(week, 30, '2016/01/01') AND
DATEADD(week, 30, '2015/01/01')
THEN dbo.sales.sellinc END) AS ActualSales
This will give you the one year range between the 30th week of 2015 and 2016, using the SQL Server week, whose first week begins on January 1st, regardless of the day. If you really want to use the ISO week, then it will be a lot more work.

How to get date of last week's X day for any month from provided date or from GetDate() for current month

Reverse question is -
How to determine if the date is in last week of month?
For example, using GetDate() how would I know that today's date or given date is in last week of the month.
As week number in MSSQL can be 4 or 5.
Suppose I want to get date of last Saturday of every month.
But in SQL week number 5 (which is last week of Dec 2013) for Dec 2013 don't have Friday. Last week of December ends with Tue on 31st.
So, I need to skip Dec and go further for January 2014 but there also last week ends on Friday 31st.
So, keep moving....
So, how to get date of last week's X day from given date or today's date?
Thanks.
You can use the code below. It is based on week starting on Monday and ending on Sunday:
declare #date as date = '20131230' -- this is the date you check
declare #lastdayofmonth as date = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#date)+1,0))
declare #lastweekstart as date = dateadd(d, -datepart(dw, #lastdayofmonth)+2, #lastdayofmonth)
if datepart(m, #lastdayofmonth) <> datepart(m, #lastweekstart)
set #lastweekstart = dateadd(d, -7, #lastweekstart)
if #date >= #lastweekstart and #date <= #lastdayofmonth
print 'Within last week'
else
print 'Not within last week'

How to create list of weeks corresponding to a month in SQL?

I need to create a report that looks like the following ("WE" is week-ending Sun to Sat):
SEPT.
WE 9/10 WE 9/17 WE 9/24 WE 10/1
Metric#1 40 49 58 40
Metric#2 24 25 20 1
The above may not be correct, it's just an example of the format.
My issue is I don't know which weeks correspond to which months. For example, the week of Oct 30 to Nov 5, I don't know which month it belongs to.
They've given me flexibility on how to do this. As long as it's consistent, it should ok.
I could also use the month of that week's Sunday (oct 30- nov-5 would be an October week because Oct 30 is a Sunday).
Could use some help here on figuring out how to assign a week to a particular month. I can do the pivoting, it's the date logic that I'm not sure about. The report is for the past 3 months.
SQL Server 2008. Report will be in SSRS 2008 R2
edit: Just got the requirements from the client. The month that has the most number of days in that week. For example Aug 28 to sept 3, for that week there are 4 days in August and 3 days in Sept, so that week belongs in August. I'll see if I can work this out.
You can use dates of Wednesdays to determine which months the corresponding weeks belong to. Your query might look something like this:
WITH marked AS (
SELECT
*,
WednesdayDate = DATEADD(DAY, 4 - DATEPART(WEEKDAY, DateColumn), DateColumn)
FROM atable
),
grouped AS (
SELECT
WeekYear = YEAR(WednesdayDate),
WeekMonth = MONTH(WednesdayDate),
WeekEnding = DATEADD(DAY, 3, WednesdayDate),
Metric1 = AGG(...),
Metric2 = AGG(...),
...
FROM marked
GROUP BY WednesdayDate
)
SELECT *
FROM grouped
WHERE WeekYear = ...
AND WeekMonth = ...
Your next step would probably be dynamic pivoting.
A problem like this is best solved with a calendar table: http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
Basically, you build a table of days (10 years of days is only 3652 rows), and you associate each date with the week you want to assign it.
Your additional requirement means that the month of the week will always be the month of the week's Wednesday (since you have Sun-Sat weeks.)
So something like this will get you the month for any date:
DECLARE #TestDate DATETIME
SET #TestDate = 'October 31, 2011'
SELECT
DATEADD(week, DATEDIFF(week, 0, #TestDate), 2) AS WednesdayOfWeek, -- This is Wednesday of the week.
DATEPART(MONTH, DATEADD(week, DATEDIFF(week, 0, #TestDate), 2)) AS MonthNum,
DATENAME(MONTH, DATEADD(week, DATEDIFF(week, 0, #TestDate), 2)) AS MonthName,
DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(week, DATEDIFF(week, 0, #TestDate), 2)), 0) AS FirstOfMonth