如何将日期分组为周?
Posted
技术标签:
【中文标题】如何将日期分组为周?【英文标题】:How to group dates into weeks? 【发布时间】:2021-06-03 21:35:31 【问题描述】:我有下表:
我不知何故设法编写了一个查询,该查询允许我对动物园每天的游客总数(如表格)进行汇总和分组,但我需要进一步分组为几周,以计算增长的百分比过去 4 周数据中每周的访问者数量。
如何在 Access SQL 中做到这一点?
这是查询:
SELECT TOP 35 date_info.calendar_date, Sum(restaurants_visitors.reserve_visitors) AS SUMreserve_visitors
FROM date_info INNER JOIN restaurants_visitors ON date_info.calendar_date = restaurants_visitors.visit_date
GROUP BY date_info.calendar_date
ORDER BY date_info.calendar_date DESC;
【问题讨论】:
【参考方案1】:Access 将日期存储为浮点数,其整数部分表示自 1900 年以来的天数,其小数部分是表示为一天的小数部分的时间。如果我将日期除以 7 并截断为整数,我将有一个从周六到周五的周数。把它放在 Group By 中就可以了。
Group By Fix(date_info.calendar_date/7)
【讨论】:
【参考方案2】:首先,您需要一个函数来计算周数。还有周数,因为周数可以跨越新年。
你可以像2021W23
这样的格式来有序地列出:
' 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 WSeparator 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(WSeparator, 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
Const MaxMonthValue As Integer = 12
Const MinMonthValue As Integer = 1
Const MaxWeekValue As Integer = 53
Const MinWeekValue As Integer = 1
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
现在您可以创建这样的查询来列出上周和 4 周前的访问者数量:
SELECT
FormatWeekIso8601(date_info.calendar_date) As Year_Week,
Sum(restaurants_visitors.reserve_visitors) AS SUMreserve_visitors
FROM
date_info
INNER JOIN
restaurants_visitors
ON date_info.calendar_date = restaurants_visitors.visit_date
GROUP BY
FormatWeekIso8601(date_info.calendar_date)
HAVING
FormatWeekIso8601(date_info.calendar_date) Between
FormatWeekIso8601(DateAdd("ww", -4, date_info.calendar_date)) And
FormatWeekIso8601(DateAdd("ww", -1, date_info.calendar_date))
ORDER BY
FormatWeekIso8601(date_info.calendar_date) DESC;
来源:VBA.Date
【讨论】:
以上是关于如何将日期分组为周?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据从 objectId 中提取的创建日期对 MongoDB 集合进行分组?