SQL - 如何根据日期范围丢弃结果组(微软访问)

时间:2016-02-10 14:27:29

标签: sql date ms-access recursion duplicates

我有许多患者的病理学结果的Access数据库,其通常包括在一段时间内为同一患者收集的许多样本。我希望为每位患者保留第一条记录,但丢弃14天内发生的同一患者的所有后续记录。但如果14天后有更多的样品,请保留第一个样品,然后再从以下14天丢弃样品。

该表包含许多列,但最重要的是patient IDsample collection date

我需要了解如何编写SQL语句来选择那些初始记录,但在随后的14天内丢弃这些记录。我认为它可能与between命令有关,但我不确定如何使开始和结束日期变量以及如何使其在整个数据集上进行递归。

3 个答案:

答案 0 :(得分:0)

不确定如何在SQL中完全执行此操作,但这里有一些(带注释的)VBA代码,我认为这样做是您要求的:

Dim db As DAO.Database
Dim strSql As String
Dim rsPat As DAO.Recordset

Set db = CurrentDb

' Get ourselves an ordered list of unique patients to work through

strSql = "SELECT PatientID " _
       & " FROM tblPatientSamplesExample" _
       & " GROUP BY PatientID" _
       & " ORDER BY PatientID"

Set rsPat = db.OpenRecordset(strSql)

With rsPat

    If _
        Not (.BOF And .EOF) _
    Then

        .MoveFirst

        Do While Not .EOF

            ' For the patient we're working on, make another list that shows the records
            ' in our table for this particular patient, ordered by the sample collection date

            Dim rsPatSampRecs As DAO.Recordset
            Dim refDate As Variant
            Dim currDate As Variant

            strSql = "SELECT * " _
                   & " FROM tblPatientSamplesExample" _
                   & " WHERE PatientID=" & rsPat!PatientID _
                   & " ORDER BY SampleCollectionDate ASC"

            Set rsPatSampRecs = db.OpenRecordset(strSql)

            With rsPatSampRecs

                If _
                    Not (.BOF And .EOF) _
                Then

                    .MoveFirst
                    ' Set the earliest sample collection date for this patient as the reference date to use
                    refDate = CDbl(rsPatSampRecs!SampleCollectionDate)

                    Do While Not .EOF

                        ' Set the current record's sample collection date for this patient as the current date to compare
                        currDate = CDbl(rsPatSampRecs!SampleCollectionDate)

                        ' if currDate is 14 or more greater than refDate then update the refDate to the currDate
                        If _
                            currDate >= (refDate + 14) _
                        Then

                            refDate = currDate

                        End If

                        ' if currDate is not the same as the refDate delete the record from
                        ' tblPatientSamplesExample by matching PatientSampleID of this temp recordset
                        ' to the one in the actual table

                        If _
                            currDate <> refDate _
                        Then

                            strSql = "DELETE * FROM tblPatientSamplesExample" _
                                   & " WHERE PatientSampleID=" & rsPatSampRecs!PatientSampleID

                            CurrentDb.Execute strSql

                        End If

                        .MoveNext

                    Loop

                End If

            End With

            rsPatSampRecs.Close
            Set rsPatSampRecs = Nothing
            .MoveNext

        Loop

    End If

End With


rsPat.Close

Set rsPat = Nothing
Set db = Nothing

Here's我的模型Access文件。我将“丢弃记录”解释为“删除记录”,因此在实施之前要小心(备份数据)。

答案 1 :(得分:0)

你试过Max()函数吗?您可以使用它为每个患者ID选择最新的SampleDate

这样的事情:

Select PatentID, Max(SampleDate)
From SpecimenTable
Where CollectionDate between Date1 and Date2
Group By PatientID

您需要在group by语句中的select语句中包含除Max(SampleDate)之外的每个字段。

答案 2 :(得分:0)

纯粹&#34; aircode&#34;,我没有太多时间专注于此,但如果它没有意义那么也许其他人可以使用它来提出一个完整的解决方案:

'Keep the first record in the first 14 days
Select PatentID, Max(SampleDate)
From SpecimenTable
Where CollectionDate between Now() and DateAdd("d", Now(), -14)
Group By PatientID

UNION ALL

'Keep the first record of everything after the first 14 days
Select PatentID, Max(SampleDate)
From SpecimenTable
Where CollectionDate < DateAdd("d", Now(), -15)
Group By PatientID

显然,您无法在查询中使用评论,因此您需要删除这些评论。我只是把它们放进去展示我的思考过程。