使用SQL合并几个相邻的日期

时间:2019-04-23 20:17:50

标签: sql ms-access

我正在尝试合并几个相邻的日期以获得一个条目。

例如,我有一名员工缺席:

02-Mai-17   01-Apr-18
02-Apr-18   01-Apr-19
02-Apr-19   01-Apr-20
02-Apr-20   30-Aug-20

结果应为: 17年2月2日至20年8月30日

我尝试用Combine consecutive date ranges合并相邻的日期,但这对我的理解仅适用于另外一个相邻的日期。

我在https://www.file-upload.net/download-13581528/Database1.accdb.html下上传了一个示例数据库

SELECT IT2001.Id, IT2001.Kind, IT2001.Start, IT2001.End, 'Typ1'
FROM IT2001 LEFT JOIN IT2001 AS IT2001_1 ON (IT2001.Id = IT2001_1.Id) AND (IT2001.Kind = IT2001_1.Kind) AND (IT2001.Start-1=IT2001_1.End)
WHERE IT2001_1.Id IS NULL 
UNION ALL
SELECT IT2001.Id, IT2001.Kind, IT2001.Start, IT2001_1.End, 'Typ2'
FROM IT2001 INNER JOIN IT2001 AS IT2001_1 ON (IT2001.Id = IT2001_1.Id) AND (IT2001.Kind = IT2001_1.Kind) AND (IT2001_1.Start-1=IT2001.End)

然后:

SELECT Query1.Id, Query1.Kind, MIN(Query1.Start), Max(Query1.End)
FROM Query1
GROUP BY Query1.Id, Query1.Kind, Query1.Start

我得到3行而不是1行:

02-Mai-17   01-Apr-19
02-Apr-18   01-Apr-20
02-Apr-19   30-Aug-20

如何获得一行或如何删除不需要的条目?

2 个答案:

答案 0 :(得分:0)

由于所有范围的总和不留间隙,因此可以:

SELECT 
    Min(IT2001.Start) AS FirstDate, 
    Max(IT2001.End) AS LastDate
FROM 
    IT2001;

答案 1 :(得分:0)

我想我已经用VBA解决了这个问题,并想邀请您评论或改善它:

Sub mergeDates()
    Set db = CurrentDb

    i = 1
    Do While i > 0
        SQL = "UPDATE (IT2001 LEFT JOIN IT2001 AS IT2001_1 ON (IT2001.Start-1 = IT2001_1.End) AND (IT2001.Id = IT2001_1.Id) AND (IT2001.Kind = IT2001_1.Kind)) LEFT JOIN IT2001 AS IT2001_2 ON (IT2001.End = IT2001_2.Start-1) AND (IT2001.Kind = IT2001_2.Kind) AND (IT2001.Id = IT2001_2.Id)" & _
            " Set IT2001.End = IT2001_2.End, IT2001.combined=NZ(IT2001.combined,0)+1, IT2001_2.Delete = true" & _
            " Where IT2001_1.Start Is Null AND IT2001_2.End IS NOT NULL"
        db.Execute SQL

        delSQL = "DELETE * FROM IT2001 WHERE delete = true"
        db.Execute delSQL
        i = db.RecordsAffected

        j = j + 1
        If (j >= 10) Then
            i = 0
        End If
    Loop

结束子

  • 我检查当前条目是否为该行的第一行(IT2001_1.Start为空),并且
  • 是否存在相邻日期(IT2001_2。结束日期不为空)。
  • 如果两个都成立,则将第二个结束日期替换为第一个结束日期(IT2001.End = IT2001_2.End),然后标记第二个要删除的条目(IT2001_2.Delete = true)
  • 我删除所有删除为true的条目(DELETE * FROM IT2001 WHERE delete = true)

我将其放入while循环中进行合并,直到获得0条受影响的记录(i = db.RecordsAffected)

有人有什么建议或改进吗?