Промежуточная сумма в запросе Access с Group By - PullRequest
1 голос
/ 04 ноября 2019

Я не могу получить промежуточную сумму для работы в запросе Access. У меня есть система трубопроводов, где я пытаюсь обобщить поток Q через пипеть. Я пытался сделать промежуточную сумму на основе group_by ID_downstream и DSum на Q_total. Однако я продолжаю получать ошибки или неправильный ввод.

Желаемый вывод, это то, что я вижу поток, накопленный через сеть, как показано в таблице и на рисунке.

enter image description here

1 Ответ

2 голосов
/ 04 ноября 2019

У вас есть несколько вариантов. Один, однако, не подойдет, и это рекурсивный запрос, использующий только SQL;Доступ не может быть одурачен и потребует циклическую ссылку. Ваш единственный шанс - создать запрос, разрешающий только ограниченное количество уровней, скажем, 8 или 10.

Но вы можете покрыть рекурсивный вызов в агрегатной функции домена, такой как DLookup. Это, однако, очень медленно, так как DLookup вызов запроса будет выполняться для каждой записи. Для более чем нескольких десятков записей это, скорее всего, будет неприемлемо.

Самый быстрый способ для неограниченного числа уровней, как я обнаружил, - это создать функцию поиска, которая обходит дерево для каждой записи. Это может выводить либо уровень записи, либо составной ключ, построенный по ключу записи и всем указанным ключам.

Поскольку функция поиска будет использовать один и тот же набор записей для каждого вызова, вы можете сделать это static , и (для 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 * 1020). *) из 0.

Теперь ваше дерево будет отображаться почти мгновенно, используя такой запрос, где Account будет видимым составным ключом:

  SELECT
    *, RecursiveLookup([ID]) AS Account
  FROM
    tblAccount
  WHERE
    AccountID > 0
  ORDER BY
    RecursiveLookup([ID]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...