【问题标题】:Running sum in Access query with Group By使用 Group By 在 Access 查询中运行 sum
【发布时间】:2019-11-04 10:30:48
【问题描述】:

我无法在 Access 查询中获得运行总和。我有一个管道系统,我试图通过管道网络总结流量 Q。我一直在尝试根据 group_by ID_downstream 和 Q_total 上的 DSum 进行运行总和。但是我不断收到错误或错误输入。

想要的输出,是我可以看到通过网络累积的流量,如表和图片所示。

【问题讨论】:

  • 您的运行总数似乎没有加起来/没有意义。您能仔细检查您向我们展示的数据吗?
  • 您正在寻找分层(即递归)查询。这在 MS Access 中是不可能的。
  • @TimBiegeleisen:请注意,D 拥有 5。因此,5+8+7+5=25。那么 25+10=35。
  • @ThorstenKettner:不是在 SQL 中,没错。但是您可以使用 VBA 中的记录集来做到这一点。

标签: sql ms-access sum


【解决方案1】:

您有多种选择。但是,一个是不行的,那就是只使用 SQL 的递归查询;访问不能被愚弄,并且会声称循环引用。您唯一的机会是创建一个仅解决有限数量级别的查询,例如 8 或 10。

但是您可以在DLookup 等域聚合函数中覆盖递归调用。然而,这非常慢,因为DLookup 调用查询将为每条记录运行。对于数十条以上的记录,这很可能是不可接受的。

我发现,对于无限数量的级别,最快的方法是创建一个查找函数,该函数遍历每个记录的树。这可以输出记录的级别或由记录的键和上面的所有键构建的复合键。

由于查找功能将为每次调用使用相同的记录集,您可以将其设为静态,并且(对于 JET/ACE)您可以通过使用Seek 来定位记录来进一步改进。

这里有一个例子可以给你一个想法:

Function RecursiveLookup(ByVal lngID As Long) As String

  Static dbs      As Database
  Static tbl      As TableDef
  Static rst      As Recordset

  Dim lngLevel    As Long
  Dim strAccount  As String

  If dbs Is Nothing Then
    ' For testing only.
    ' Replace with OpenDatabase of backend database file.
    Set dbs = CurrentDb()
    Set tbl = dbs.TableDefs("tblAccount")
    Set rst = dbs.OpenRecordset(tbl.Name, dbOpenTable)
  End If

  With rst
    .Index = "PrimaryKey"
    While lngID > 0
      .Seek "=", lngID
      If Not .NoMatch Then
        lngLevel = lngLevel + 1
        lngID = !MasterAccountFK.Value
        If lngID > 0 Then
          strAccount = str(!AccountID) & strAccount
        End If
      Else
        lngID = 0
      End If
    Wend
    ' Leave recordset open.
    ' .Close
  End With

'  Don't terminate static objects.
'  Set rst = Nothing
'  Set tbl = Nothing
'  Set dbs = Nothing

'  Alternative expression for returning the level.
'  (Adjust vartype of return value of function.) '  RecursiveLookup = lngLevel ' As Long
  RecursiveLookup = strAccount

End Function

这假定一个表具有一个主键 ID 和一个指向父记录的外(主)键 - 以及一个具有可见键 (AccountID) 的顶级记录(未使用) ) 0.

现在您的树将使用这样的查询几乎立即显示,其中 Account 将是可见的复合键:

  SELECT
    *, RecursiveLookup([ID]) AS Account
  FROM
    tblAccount
  WHERE
    AccountID > 0
  ORDER BY
    RecursiveLookup([ID]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多