问题
I currently have two tables. One has Employee Names and a number associated to that name.
The other date has time sheet date with columns for the employee number, the date and the number of hours worked on that date.
I want to create a cross tab query that shows the employee names in one column with the date for the end of the week in each column, then show to sum of hours for that week for a particular employee.
My current query works but only groups by month. I am struggle to work out how to group days into weeks.
TRANSFORM Sum(tblTimeSheetData.WorkHours) AS SumOfHours
SELECT tblEmployees.Combined
FROM tblTimeSheetData RIGHT JOIN tblEmployees ON tblTimeSheetData.EmployeeID =
tblEmployees.EmployeeID
GROUP BY tblEmployees.Combined
ORDER BY tblEmployees.Combined, Format([WorkDate],"yyyy-mm")
PIVOT Format([WorkDate],"yyyy-mm");
回答1:
As the first and last week numbers cross calendar years, both year and week number must be included:
Option Compare Database
Option Explicit
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, for a date value, a formatted string expression with
' year and weeknumber according to ISO-8601.
' Optionally, a W is used as separator between the year and week parts.
'
' Typical usage:
'
' FormatWeekIso8601(Date)
' -> 2017-23
'
' FormatWeekIso8601(Date, True)
' -> 2017W23
'
' 2017-04-28. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function FormatWeekIso8601( _
ByVal Expression As Variant, _
Optional ByVal WeekSeparator As Boolean) _
As String
Const Iso8601Separator As String = "W"
Const NeutralSeparator As String = "-"
Dim Result As String
Dim IsoYear As Integer
Dim IsoWeek As Integer
If IsDate(Expression) Then
IsoWeek = Week(DateValue(Expression), IsoYear)
Result = _
VBA.Format(IsoYear, String(3, "0")) & _
IIf(WeekSeparator, Iso8601Separator, NeutralSeparator) & _
VBA.Format(IsoWeek, String(2, "0"))
End If
FormatWeekIso8601 = Result
End Function
' 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
If you just want to pivot on the ultimo week date, you can use this expression:
DateAdd("d", 7 - Weekday([WorkDate], vbMonday), [WorkDate])
This assumes ISO week numbering where Monday is the first day of the week.
回答2:
You can try getting the week with datepart function like
SELECT DATEPART(ww, 'your date') AS week;
and then group by week.
Here more info https://www.w3schools.com/sql/func_sqlserver_datepart.asp
来源:https://stackoverflow.com/questions/57211964/ms-access-query-how-to-use-sql-to-group-single-dates-into-weeks