SQL compare Workdays - sql

Currently I have 2 years worth of Sales data, and my company wants a weekday to weekday comparison between the 2 years
basically the Sales Numbers for Wednesday April 1st 2020 should be compared to Wednesday April 3rd 2019 (weekday to weekday comparison, instead of calendar year)
i'm trying to come up with some sort of case statement that will allow me to add a helper column so I can then put it into an excel Pivot table, or use a join, but I'm a bit stumped on how to go about it
Basically I thought if I could come up with some way to assign a sequence to each workday, it could be done
for example Monday #1 in April could get the code MApril1 Monday #2 in April could get MApril2 Monday #1 in June could get MJune1 and so forth (I could just do that for both years and that would make it very easy)
but I just cant think of a way to write that sequence or case, any suggestions?
long story short lets say I gave you the date Wednesday April 8th 2020, how would you identify this as the second Wednesday of April 2020?

Not sure if I understood clearly but I will try to help.
Don't hesitate to tell me if I'm wrong.
I assumed you used SQL Server. Please add the SQL you use into the tags.
I would count the week number.
set datefirst 1; -- depending on the language
declare #weekNb int;
select #weekNb = datepart(week, #yourInitialDate); -- getting the number of the week
declare #dayNb = int;
select #dayNb = datepart(weekday, #yourInitialDate); -- getting the number of the day
And now, using the function from this post I would get the day from the current year :
select dbo.date_from_week_number_day(YEAR(GetDate(),weekNb,dayNb);

Related

How can I Format the Date so that the fiscal week starts in December?

I want to format a date as follows: Y17W15, but there is no option to set the start of the year. However, there is no consistent way of calculating this. I cannot just subtract a month (other times I will need to show the month too), and I cannot just add 4 or 5 to the week field due to leap years, etc.
Our year starts on a Saturday that is closest to December 1. This means if November 30 is on a Saturday, the Fiscal Year will start on November 30.
Currently what I have is below, which works fine except it shows Y17W10. The easiest option in my head is to have a way to actually set the start of a fiscal year, but if I have to go through a bunch of if statements it's okay as long as it works.
MsgBox(Format(Now, """Y""yy""W""mm"""))
Thanks for your time!
I am aware that: Given a 4-5-4 calendar and a date, how do I determine what fiscal week that date falls in? exists but I am looking for an answer that isn't as hard-coded.
Michael

Oracle Week Number from a Date

I am brand new to Oracle. I have figured out most of what I need but one field is driving me absolutely crazy. Seems like it should be simple but I think my brain is fried and I just can't get my head around it. I am trying to produce a Sales report. I am doing all kinds of crazy things based on the Invoice Date. The last thing I need to do is to be able to create a Week Number so I can report on weekly sales year vs year. For purposes of this report my fiscal year starts exactly on December 1 (regardless of day of week it falls on) every year. For example, Dec 1-7 will be week 1, etc. I can get the week number using various functions but all of them are based on either calendar year or ISO weeks. How can I easily generate a field that will give me the number of the week since December 1? Thanks so much for your help.
Forget about the default week number formats as that won't work for this specific requirement. I'd probably subtract the previous 1 December from invoice date and divide that by 7. Round down, add 1 and you should be fine.
select floor(
(
trunc(invoiceDate) -
case
-- if December is current month, than use 1st of this month
when to_char(invoiceDate, 'MM') = '12' then trunc(invoiceDate, 'MM')
-- else, use 1st December of previous year
else add_months(trunc(invoiceDate, 'YYYY'), -1)
end
) / 7
) + 1
from dual;

Datepart Week Sql (With 53 weeks for year)

I'm calculating the week for a specific date in SQL for example
'2016-01-20' (yyyy-mm-dd) but SQL returns week: 4, and that is wrong because this year the first week started on '2016-01-04' the result must be week: 3.
I think the issue is generatad because 2015 was a year with 53 weeks, any solution to that? Thank you and I'm sorry for my bad English
In tSQL the DATEPART() is returning the correct data based on US and Most of Europe as well as UK See here
You can use SET DATEFIRST to adjust the start position however.
The ISO 8601 definition for week 01 is the week with the year's first Thursday in it. I am using Intersystems cache which apparently does not account for that either. So I have used this to address that
CASE WHEN 7-datepart(dw,dateadd(dd,1,dateadd(yy,datediff(yy,0,getdate())-1,0))) < 2
THEN datepart(wk,getdate())-1 ELSE datepart(wk,getdate()) END as WeekNum

Get month name with different month start and end dates

Getting the month for the current date is, obviously, straight forward, but I'm needing to get the month name with a different end date.
I need to get the month name with the start date of the month being the first Thursday after the first Wednesday of the month and the end date of the month being the first Wednesday of the following month. It's for an accounting thing, so I'm not going to argue with the spec!
e.g. for 2014, January would run from 9th Jan - 5th Feb, February would run from 6th February - 5th March, March would run from 6th March - 2nd April.
I would suggest that you create a table with your 'accounting months' in it, having a start date, end date and month name columns.
You could then query this to find the row where your date is between the start and end dates and return the month name. Putting this into a scalar function would then allow it to be reusable and relatively easily updated for next years months as well.
I think, as per Paddy's answer, a lookup table is the simplest thing to do. Here's one way to generate the rows for it:
; With Numbers(n) as (
select 4 union all select 5
), Months as (
select CONVERT(date,'20010104') as StartDt,CONVERT(date,'20010207') as EndDt,
DATENAME(month,'20010103') as Month
union all
select DATEADD(week,n1.n,StartDt),DATEADD(week,n2.n,EndDt),
DATENAME(month,DATEADD(week,n1.n,StartDt))
from Months,Numbers n1,Numbers n2 --Old-skool join, just for once
where DATEPART(day,DATEADD(week,n1.n,StartDt)) between 2 and 8 and
DATEPART(day,DATEADD(week,n2.n,EndDt)) between 1 and 7 and
StartDt < '21000101'
)
select * from Months option (maxrecursion 0)
(CW since this is effectively just an extension to Paddy's answer but I don't want to edit their answer, nor is it suitable for a comment

Access query (SQL) to return records sorted (grouped by) WEEKS

Greetings SQL gurus,
I don't know if you can help me, but I will try. I have several large databases grouped by year (each year in a different database). I want to be able to compare values from a particular week from one year to the next. For example, "show me week 17 of 2008 vs. week 17 of 2002."
I have the following definition of weeks that ideally I would use:
Only 52 weeks each year and 7 days a week (that only takes 364 days),
The first day of the first week starts from January 2nd - which means we do not use January 1st data, and
In leap year, the first day of the first week ALSO starts from the January 2nd plus we skip Feb. 29.
Any ideas?
Thanks in advance.
Best to avoid creating a table because then you have to update and maintain it to get your queries to work.
DatePart('ww',[myDate]) will give you the week number. You may run into some issues though deciding which week belongs to which year - for example if Jan 1 2003 is on Wednesday does the week belong as week 52 in 2002 or week 1 in 2003? Your accounting department will have a day of the week that is your end of week (usually Sat). I usually just pick the year that has the most days in it. DatePart will always count the first week as 1 and in the case of the example above the last week as 53. You may not care that much either way. You can create queries for each year
SELECT DatePart('ww',[myDate]) as WeekNumber,myYearTable.* as WeekNumber
FROM myYearTable
and then join the queries to get your data. You'll loose a couple days at the end of the year if one table has 52 weeks and one has 53 (most will show as 53). Or you can do it by your weekending day - this always gives you Saturday which would push a late week into the following year.
(7-Weekday([myDate]))+[myDate]
then
DatePart('ww',(7-Weekday([myDate]))+[myDate])
Hope that helps
To get the week number
'to get the week number in the year
select datepart( week, datefield)
'to get the week number in the month
select (datepart(dd,datefield) -1 ) / 7 + 1
You don't need to complicate things thinking about leap years, etc. Just compare weeks mon to sun
SInce you havea a specifc defintion of when the week starts that is differnt that the standard used by the db, I think a weeks table is the solution to your problem. For each year create a table that defines the dates contained in each week and the week number. Then by joining to that table as well as the relevant other tables, you can ask for just the data for week 17.
Table structure
Date Week
20090102 1
20090103 1
etc.
I needed to create a query that shows BOTH year AND week numbers, like 2014-52. The year shows correct when you use the Datepart() formula to convert week 53 to week 52 in the previous year, but shows the wrong year for the week that was week 1 previously that should be week 52 now. It show that week as 2015-52 instead of 2014-52.
Furthermore, it sorts the data wrong if you only use only the week number, eg:
2014-1,2014-11,2014-2
To overcome this I created the following query to insert a 0 and also to check for days in week 1 that should still fall under week 52.
ActualWeek: IIf(DatePart("ww",[SomeDate],1,3)=52 And DatePart("ww",[SomeDate])=1, DatePart("yyyy",[SomeDate],1,3)-1,DatePart("yyyy",[SomeDate],1,3)) & "-" & IIf(DatePart("ww",[SomeDate],1,3)<10,"0" & DatePart("ww",[SomeDate],1,3),DatePart("ww",[SomeDate],1,3))