用于从以日期列为决策标准的数据库中删除不正确项的SQL查询

用于从以日期列为决策标准的数据库中删除不正确项的SQL查询,sql,oracle,Sql,Oracle,由于不正确的插入,我在数据库中有几个错误的条目。这些事件以四人一组的形式发生。示例: ID_A Startdate Enddate ID_B 296 05.09.2013 28.10.2017 62 296 05.09.2013 01.01.2999 62 296 28.10.2017 05.09.2013 65 296 28.10.2017 01.01.2999 65 285 26.02.2016 07.0

由于不正确的插入,我在数据库中有几个错误的条目。这些事件以四人一组的形式发生。示例:

ID_A  Startdate     Enddate      ID_B
296   05.09.2013    28.10.2017   62
296   05.09.2013    01.01.2999   62
296   28.10.2017    05.09.2013   65
296   28.10.2017    01.01.2999   65

285   26.02.2016    07.09.2018   93
285   26.02.2016    01.01.2999   93
285   07.09.2018    26.02.2016   58
285   07.09.2018    01.01.2999   58
给定期间只能有一个有效条目。第二个和第三个条目不属于表中,必须删除。第一个条目的结束日期必须与下一个条目的开始日期相同。我可以很容易地识别第三个条目,因为结束日期小于开始日期

Delete from table where ID_A = 296 and Enddate < Startdate
有人知道我该怎么做吗?

你可以在下面试试-

Delete from table t1
where exists (select 1
              from table t2
              where t1.ID_A = t2.ID_A
              and t1.Startdate = t2.Startdate
              and t1.ID_B = t2.ID_B
              and t1.Enddate > t2.Enddate)
你可以在下面试试-

Delete from table t1
where exists (select 1
              from table t2
              where t1.ID_A = t2.ID_A
              and t1.Startdate = t2.Startdate
              and t1.ID_B = t2.ID_B
              and t1.Enddate > t2.Enddate)
我认为你可以做到:

delete from t
    where not exists (select 1
                      from t t2
                      where t2.startdate = t.enddate
                     ) and
          exists (select 1
                  from t t2
                  where t2.startdate < t.startdate or
                        (t2.startdate = t.startdate and t2.enddate < t.enddate)
                 );
他是一把小提琴

这适用于您的示例数据。它检查当前记录之前是否有匹配的记录,并且当前记录不是第一个记录。它不会适用于所有的化身。事实上,您可能有一些复杂的交错记录,其中单个解决方案不明显。

我认为您可以:

delete from t
    where not exists (select 1
                      from t t2
                      where t2.startdate = t.enddate
                     ) and
          exists (select 1
                  from t t2
                  where t2.startdate < t.startdate or
                        (t2.startdate = t.startdate and t2.enddate < t.enddate)
                 );
他是一把小提琴


这适用于您的示例数据。它检查当前记录之前是否有匹配的记录,并且当前记录不是第一个记录。它不会适用于所有的化身。事实上,您可能会有一些复杂的交错记录,其中单个解决方案并不明显。

1用您正在使用的数据库标记您的问题。2你确定没有其他情况吗?@GordonLinoff对此表示抱歉。2只有在这种情况下才会出现错误。那么,以下两类中只有一类是错误吗?如果你删除了所有这些错误,剩下的是正确的吗?这两类是:1 ENDDATE小于STARTDATE;2 ENDDATE为2999年1月1日,但同一ID_A有两行或多行与此ENDDATE相同;在这些行中,只有起始日期最大的一行是正确的,其他所有行都是错误的。是吗?@mathguy我想明确地保留一个条目,其中最小的起始日期在过去有一个结束日期。此外,我希望在将来保留将enddate作为startdate和enddate的条目。从每组中选出第一个和最后一个条目。1用您正在使用的数据库标记您的问题。2你确定没有其他情况吗?@GordonLinoff对此表示抱歉。2只有在这种情况下才会出现错误。那么,以下两类中只有一类是错误吗?如果你删除了所有这些错误,剩下的是正确的吗?这两类是:1 ENDDATE小于STARTDATE;2 ENDDATE为2999年1月1日,但同一ID_A有两行或多行与此ENDDATE相同;在这些行中,只有起始日期最大的一行是正确的,其他所有行都是错误的。是吗?@mathguy我想明确地保留一个条目,其中最小的起始日期在过去有一个结束日期。此外,我希望在将来保留将enddate作为startdate和enddate的条目。从每组中删除第一个和最后一个条目。您的方法根据需要删除第二个条目,但也删除我要保留的第四个条目。知道我如何删除第二和第三个条目并保留第一和最后一个吗?@wannaBeDev。最早的开始日期是重复的。我调整了逻辑并添加了一个DBFIDLE。我不得不修改它以满足我的需要。但你把我带向了正确的方向。感谢链接到dbfiddle。您的方法会根据需要删除第二个条目,但也会删除我要保留的第四个条目。知道我如何删除第二和第三个条目并保留第一和最后一个吗?@wannaBeDev。最早的开始日期是重复的。我调整了逻辑并添加了一个DBFIDLE。我不得不修改它以满足我的需要。但你把我带向了正确的方向。感谢链接到dbfiddle。您的方法会根据需要删除第二个条目,但也会删除我要保留的第四个条目。你知道我如何删除第二条和第三条,并保留第一条和最后一条吗?你的方法会根据需要删除第二条,但也会删除我想要保留的第四条。你知道我如何删除第二和第三条,保留第一和最后一条吗?