Reputation: 29
I am sure i am missing something obvious, but i cant figure this out. My problem is very simple i have a table that contains the following information:
Year, Weeknumber, Data
What i want is to SELECT only data where the weeknumber is less that the current week. That is easy. But what i really want is all data that is registered before the current weeknumber AND current year. Meaning if i have the following data:
Year Week Data
2019 20 123
2019 21 234
2020 20 345
2020 21 456
If the current week is 21 of 2020 then i want the output to be:
year Week Data
2019 20 123
2019 21 234
2020 20 234
I dont want 2020 - 21 because that is the current year/week My current query is:
SELECT T.Year, T.Week, T.Data
FROM tblData AS T
WHERE Year<=year(Date()) AND Week<Weeknumber(Date())
The problem with this query is that it doesnt show weeks above 21 in 2019 which i want it to do. I know why this sql doesnt work, but cant figure out how to do it correctly.
How do i do this?
Upvotes: 1
Views: 72
Reputation: 21370
Year is a reserved word and should not use reserved words as names for anything. I used Yr as field name.
Consider:
SELECT Yr, Week, Data
FROM Table1
WHERE [Week] Between 1 And IIf([Yr]=Year(Date()), DatePart("ww", Date()) - 1, 53);
Upvotes: 1
Reputation: 55831
As you are from Denmark, the table will most likely reflect years and weeks according to ISO 8601. However, no native function of VBA will return the ISO 8601 year and week of a date, and - for dates around New Year - the year will often differ from the calendar year.
Thus, functions to return the ISO 8601 year and week are needed:
Public Const MaxWeekValue As Integer = 53
Public Const MinWeekValue As Integer = 1
Public Const MaxMonthValue As Integer = 12
Public Const MinMonthValue As Integer = 1
' Returns the ISO 8601 week of a date.
' The related ISO year is returned by ref.
'
' 2016-01-06. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function Week( _
ByVal Date1 As Date, _
Optional ByRef IsoYear As Integer) _
As Integer
Dim Month As Integer
Dim Interval As String
Dim Result As Integer
Interval = "ww"
Month = VBA.Month(Date1)
' Initially, set the ISO year to the calendar year.
IsoYear = VBA.Year(Date1)
Result = DatePart(Interval, Date1, vbMonday, vbFirstFourDays)
If Result = MaxWeekValue Then
If DatePart(Interval, DateAdd(Interval, 1, Date1), vbMonday, vbFirstFourDays) = MinWeekValue Then
' OK. The next week is the first week of the following year.
Else
' This is really the first week of the next ISO year.
' Correct for DatePart bug.
Result = MinWeekValue
End If
End If
' Adjust year where week number belongs to next or previous year.
If Month = MinMonthValue Then
If Result >= MaxWeekValue - 1 Then
' This is an early date of January belonging to the last week of the previous ISO year.
IsoYear = IsoYear - 1
End If
ElseIf Month = MaxMonthValue Then
If Result = MinWeekValue Then
' This is a late date of December belonging to the first week of the next ISO year.
IsoYear = IsoYear + 1
End If
End If
' IsoYear is returned by reference.
Week = Result
End Function
' Returns the ISO 8601 year of a date.
'
' 2016-01-06. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function YearOfWeek( _
ByVal Date1 As Date) _
As Integer
Dim IsoYear As Integer
' Get the ISO 8601 year of Date1.
Week Date1, IsoYear
YearOfWeek = IsoYear
End Function
An example:
? Week(#2024/12/31#)
1
? YearOfWeek(#2024/12/31#)
2025
Now, use these in your query:
SELECT
T.Year,
T.Week,
T.Data
FROM
tblData AS T
WHERE
T.Year * 100 + T.Week < YearOfWeek(Date()) * 100 + Week(Date())
And you can safely keep Year as the field name as long as you prefix it in queries with the table name as you already do or wrap it in brackets: [Year]
.
Upvotes: 1
Reputation: 29
After further testing, June7 was very close, but that sql ended up removing the weeks greater than current week in 2019 (Which i didnt want). I might not have been clear enough in my question, but here is the sql WHERE criteria that gave me what i wanted. Which is, i only want the query to remove data from the current week in the current year. everything older than that, i want shown.
WHERE tbl.Week Between 1 And IIf(tbl.Yr=Year(Date()),Datepart("ww",Date())-1,53)
but thanks for your help @June7, since you guided me straight to the answer
Upvotes: 0