Группировка нескольких записей «in» и «out» в «сессии». По запросу SQL или программированием - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть таблица (в Microsoft Access, но может быть на SQL сервере или аналогичной) с рабочим входом / выходом из реестра.

Каждое 'In' работника - это запись с его PersonalID , TimeOfEvent и тип события («In» или «Out»).

В конце пути - мне придется вычислять разницу во времени между каждым «In» и «Out».

Но в качестве среднего шага - я хочу сделать групповой запрос (в построителе запросов Microsoft Access или написать предложение SQL), который добавит уникальный «SessionID» к каждой паре «In» и "Out" запись. Таким образом, у меня будет много «Сессий», каждая из которых имеет 2 записи - один и тот же PersonID, одно событие «In» и выходное «Out» событие, позднее, чем связанное с ним событие «In».

Такой запрос был бы хорош, но для меня также было бы возможно написать вспомогательную функцию VBA или более сложное SQL внутреннее объединение.

Любая помощь приветствуется!

1 Ответ

1 голос
/ 28 апреля 2020

Этот вопрос помечен vb. net, поэтому я предполагаю, что это вариант, хотя в вопросе говорится VBA. Кроме того, у нас недостаточно информации для полного решения, поэтому вот код, который можно использовать для выполнения основных задач. Вам нужно будет заполнить остальные, где это необходимо, или вернуться сюда с более конкретным c вопросом.

Public Class Session
    Public PersonId As Integer
    Public SessionStart As DateTime
    Public SessionEnd As Nullable(Of DateTime)

    Public Sub New(Id As Integer, Start As DateTime)
        PersonId = Id
        SessionStart = Start
    End Sub

End Class

//Assumes dt contains your list of events
Public Function GetSessions(dt As DataTable) As List(Of Session)

    Dim Sessions As New List(Of Session)
    Dim OpenSession As Session
    For Each rw As DataRow In dt.Rows
        Dim id As Integer = CInt(rw("PersonID"))
        OpenSession = (From s As Session In Sessions
                       Where s.PersonId = id AndAlso s.SessionEnd Is Nothing
                       Select s).FirstOrDefault()

        If CBool(rw("In")) Then
            If OpenSession IsNot Nothing Then
                //Two In records found with no Out between.  Handle that error here.
            Else
                Sessions.Add(New Session(id, rw("TimeOfEvent")))
            End If
        Else
            If OpenSession Is Nothing Then
                //Out record found with no matching In.  Handle that error here.
            Else
                OpenSession.SessionEnd = rw("TimeOfEvent")
            End If
        End If
    Next

    //This code finds any unclosed sessions.  Up to you whether that's an error or not.  If not, just remove them from the Sessions list
    Dim OpenSessions As List(Of Session) = (From s As Session In Sessions
                                            Where s.SessionEnd Is Nothing
                                            Select s).ToList()


    Return Sessions  'This is a list of sessions containing Id, Start & End time.  Do what you want with it

End Function
...