【问题标题】:SQL find duplicate active records between two date rangesSQL 查找两个日期范围之间的重复活动记录
【发布时间】:2019-11-09 07:19:53
【问题描述】:

我有两个表,一个患者表和一个保险表。一名患者可以拥有多项保险。我正在尝试查找所有具有重叠有效日期或显示两个有效日期的保险。

PATID    START_DTTM           END_DTTM
1        2002-09-10 00:00:00.000  NULL
1        2007-03-06 10:18:00.000  2019-04-11 11:59:00.000

如果 END_DTTM 为 Null,则它处于活动状态。开始日期应在后续结束日期结束时开始。我正在尝试查找活动日期重叠的所有条目,或者如果有意义的话,它会在一段时间内显示两个活动条目?

此外,患者还可以拥有多种保险,上面的示例显示了一位患者拥有两种保险详情。他们也可以有第三或第四个条目......

任何帮助都会很棒

【问题讨论】:

  • 期望的结果是什么?假设患者有 4 份在特定日期有效的保险,例如 2007-03-06。那么查询应该产生什么结果呢?
  • 返回所有有效日期重叠的患者和保险。然后有人可以进入系统并更正这些数据。如果一位患者有 4 个重叠的保险详细信息,那么我想退回所有 4 个@Serg
  • OK 重叠保险是 (a,b,c) (c,d) (d,e,f) 查询应该产生什么结果?只有 6 行 a、b、c、d、e、f 还是什么?
  • 是的,如果它返回所有我想那会很好。基本上日期不应该重叠。如果他们确实退还了保险,以便我们可以在系统上进行更正。迁移的保险详细信息导致重叠。

标签: sql date sql-server-2008


【解决方案1】:

这将列出至少有一个其他保险重叠的所有保险。

select ID, PATID, START_DTTM, END_DTTM
from insurances i1
where exists (select null 
              from insurances i2
              where i1.ID != i2.ID and i1.PATID = i2.PATID
                and (i1.START_DTTM  <= i2.END_DTTM or i2.END_DTTM is null)
                and (i2.START_DTTM  <= i1.END_DTTM or i1.END_DTTM is null)
             )
order by PATID, START_DTTM;

两个有效保险(结束日期为空)被视为重叠。如果相同的开始/结束日期不被视为重叠,您可能希望将 &lt;= 更改为 &lt;

【讨论】:

  • 这似乎也返回了非重复项?患者 a 的保险开始日期为 01012018 结束日期为 01012019,则新保险将从 01012019 开始,结束日期为空。这是活动的并且不重叠,因此不应该包括在内。但似乎包含在您上面的代码中?
  • @Conger88,不,它不会因为结束日期为空而返回保险。仅当存在其他在该保险开始后结束或结束日期为空的保险时。两个有效的保险(结束日期为空)被认为是重叠的。
  • 我将
【解决方案2】:

如果您的保险表也有每个保险的唯一 ID(我们希望如此),那么您可以进行这样的查询

declare @tab table (
    patid int
    , insid int
    , start_dttm datetime
    , end_dttm datetime
)

insert into @tab values (1, 8, '2002-09-10', NULL)
                        , (1, 9, '2007-03-06', '2019-04-11')
                        , (53, 321513, '2015-01-13', NULL )
                        , (53, 11, '2008-08-14', '2015-01-13')
                        , (54, 12, '2015-01-13', NULL )
                        , (54, 13, '2008-08-14', '2015-01-12')

select      a.*
            , b.*
            , 'Insurance record ' + cast(b.insid as varchar) + ' (' + convert(varchar,b.start_dttm,103) + ' to ' + convert(varchar,b.end_dttm,103) + ') '
             + 'overlaps Insurance record ' + cast(a.insid as varchar) + ' (' + convert(varchar,a.start_dttm,103) + isnull(' to ' + convert(varchar,a.end_dttm,103), ' still active') + ')'

from        @tab a
inner join  @tab b
on          a.patid = b.patid
and         a.insid != b.insid
where       (b.start_dttm > a.start_dttm and b.start_dttm < isnull(a.end_dttm, getdate()+1))
or          (b.end_dttm > a.start_dttm and b.start_dttm < isnull(a.end_dttm, getdate()+1))
or          (a.end_dttm is null and b.end_dttm is null)

注意 - 您不需要像我一样创建表变量 @tab,只需使用您的保险表即可。

【讨论】:

  • 是的,保险表有一个唯一的 ID。好的,所以我将您的查询与我的表一起使用,如下所示 select * from dbo.PATIENT_INSURANCE_DETAILS a inner join dbo.PATIENT_INSURANCE_DETAILS b on a.PATNT_REFNO = b.PATNT_REFNO and a.PATIN_REFNO != b.PATIN_REFNO where b.start_dttm between a.start_dttm and isnull(b.end_dttm, getdate()+1) or b.end_dttm between a.start_dttm and isnull(a.end_dttm, getdate()+1) ORDER BY a.PATNT_REFNO 这看起来也返回有效条目。所以我不想包含不重叠的条目
  • 我的查询中有错字,所以我进行了编辑。还添加了另一个条款来捕捉患者拥有多种有效保险的情况
  • 这似乎仍然包含有效的非重叠条目?下面的示例 PATIN_REFNO PATNT_REFNO PERCA_REFNO START_DTTM END_DTTM 321513 53 NULL 2015-01-13 00:00:00.000 NULL 11 53 NULL 2008-08-14 23:59:00.000 2015-01-13 00:00:00.000
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 2021-06-19
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多