【问题标题】:Aggregate function error when ORDER BY on timeStamp Access VBA / Excel按时间戳访问 VBA / Excel 时 ORDER BY 时聚合函数错误
【发布时间】:2016-12-22 07:16:25
【问题描述】:

Access 数据库包含 machinepark 的 logData。出于管理目的,我需要一些使用 Excel 生成的图形。数据是使用 VBA 查询从 Access 获取的。到现在为止还挺好。 除了 dateStamp 之外,还存储了一个周数(因为 Access/Excel 存在 ISO 周数问题)。但是,如果我提取 2016 年 1 月的数据,它不仅包含第 1-4 周,还包含 2016 年的第 53 周。我想将其排序为 53、1、2、3、4。 最后一步失败并出现错误:

"您的查询不包含指定的表达式 Format$(logData.dateStamp,'yyyy/mm') 作为 聚合函数。”

使用下面的 SQL 查询:

TRANSFORM  sum((logData.hoursDay+logData.hoursNight)*60) 
SELECT reasons.reason FROM reasons 
INNER JOIN (logData INNER JOIN testRigs ON logData.machine = machines.ID) ON reasons.ID = logData.reason 
WHERE  Format$(logData.dateStamp,'mm') =  1  
AND machines.type = "A" 
GROUP BY reasons.reason 
ORDER BY Format$(logData.dateStamp,'yyyy/mm') DESC
PIVOT logData.week;

AVG() 和 COUNT() 等聚合函数可以但在 SELECT 语句中,但我不需要此列。

任何提示如何正确排序周?

【问题讨论】:

  • 如果您不能在 Group By 部分中使用该表达式,则必须删除它和 Order By 部分和 枢轴不是周,而是年和周。请参阅下面的功能。

标签: excel ms-access sql-order-by vba


【解决方案1】:

您不必存储周数,但是对于给定的日期,您必须同时找到年份和星期才能获得正确的排序。

这个函数就是这样做的:

Public Function ISO_WeekYearNumber( _
  ByVal datDate As Date, _
  Optional ByRef intYear As Integer, _
  Optional ByRef bytWeek As Byte) _
  As String

' Calculates and returns year and week number for date datDate according to the ISO 8601:1988 standard.
' Optionally returns numeric year and week.
' 1998-2007, Gustav Brock, Cactus Data ApS, CPH.
' May be freely used and distributed.

  Const cbytFirstWeekOfAnyYear  As Byte = 1
  Const cbytLastWeekOfLeapYear  As Byte = 53
  Const cbytMonthJanuary        As Byte = 1
  Const cbytMonthDecember       As Byte = 12
  Const cstrSeparatorYearWeek   As String = "W"

  Dim bytMonth                  As Byte
  Dim bytISOThursday            As Byte
  Dim datLastDayOfYear          As Date

  intYear = Year(datDate)
  bytMonth = Month(datDate)
  bytWeek = DatePart("ww", datDate, vbMonday, vbFirstFourDays)

  If bytWeek = cbytLastWeekOfLeapYear Then
    bytISOThursday = Weekday(vbThursday, vbMonday)
    datLastDayOfYear = DateSerial(intYear, cbytMonthDecember, 31)
    If Weekday(datLastDayOfYear, vbMonday) >= bytISOThursday Then
      ' OK, week count of 53 is caused by leap year.
    Else
      ' Correct for Access97/2000+ bug.
      bytWeek = cbytFirstWeekOfAnyYear
    End If
  End If

  ' Adjust year where week number belongs to next or previous year.
  If bytMonth = cbytMonthJanuary Then
    If bytWeek >= cbytLastWeekOfLeapYear - 1 Then
      ' This is an early date of January belonging to the last week of the previous year.
      intYear = intYear - 1
    End If
  ElseIf bytMonth = cbytMonthDecember Then
    If bytWeek = cbytFirstWeekOfAnyYear Then
      ' This is a late date of December belonging to the first week of the next year.
      intYear = intYear + 1
    End If
  End If

  ISO_WeekYearNumber = CStr(intYear) & cstrSeparatorYearWeek & Format(bytWeek, "00")

End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多