【问题标题】:Need to select records that have overlapping date ranges for same product groupings需要为相同的产品分组选择具有重叠日期范围的记录
【发布时间】:2017-06-15 16:17:28
【问题描述】:
create table #productcov  
(  
[group] varchar(20), -- as business  
account varchar(10), -- as business location  
member  varchar(10), -- as member  
product varchar(10), -- as health product  
[plan]  varchar(10), -- as product type  
StartTime datetime,  -- as beginning of coverage period  
EndTime datetime     -- as end of coverage period  
) 
go  

insert into #productcov values 

('NN00001','10001','1234567890','ADD','A1000','2010-10-01 00:00:00' , '2012-09-30 00:00:00'),  
('NN00001','10001','1234567890','ADD','A1000','2012-10-01 00:00:00' , '2013-09-30 00:00:00'),  
('NN00001','10001','1234567890','ADD','A1000','2013-01-01 00:00:00' , '2013-12-31 00:00:00'),   
('NN00001','10001','1234567890','ADD','B1000','2010-01-01 00:00:00' , '2014-12-31 00:00:00'),    
('NN00001','10001','1234567890','ADD','B1000','2015-01-01 00:00:00' , '2016-12-31 00:00:00'),  
('NN00001','10001','1234567890','LIF','A1000','2010-10-01 00:00:00' , '2012-09-30 00:00:00'),  
('NN00001','10001','1234567890','LIF','A1000','2012-10-01 00:00:00' , '2013-09-30 00:00:00'),  
('NN00001','10001','1234567890','LIF','A1000','2013-01-01 00:00:00' , '2013-12-31 00:00:00'),  
('NN00001','10001','1234567890','LIF','B1000','2010-01-01 00:00:00' , '2014-12-31 00:00:00'),  
('NN00001','10001','1234567890','LIF','B1000','2015-01-01 00:00:00' , '2016-12-31 00:00:00')

select * from   #productcov

上面的示例表适用于单个组中的单个成员。我试图从#productcov 表中的十条记录中仅选择第二条和第三条以及第七条和第八条记录,其中医疗产品的承保日期与成员的产品重叠。这是一个审计过程,用于清理覆盖日期中的重叠数据。表中重要的重叠日期需要按组、帐户、成员、产品和计划进行分组。

我几天来一直在尝试寻找解决方案,但结果一无所获!任何帮助表示赞赏。

所需的输出将是下面列出的 4 条记录:

组、帐户、成员、产品、计划、开始日期、结束日期

'NN00001','10001','1234567890','ADD','A1000','2012-10-01 00:00:00','2013-09-30 00:00:00',

'NN00001','10001','1234567890','ADD','A1000','2013-01-01 00:00:00','2013-12-31 00:00:00'

'NN00001','10001','1234567890','LIF','A1000','2012-10-01 00:00:00','2013-09-30 00:00:00'

'NN00001','10001','1234567890','LIF','A1000','2013-01-01 00:00:00','2013-12-31 00:00:00'

【问题讨论】:

    标签: sql date datetime select overlap


    【解决方案1】:

    您可以使用exists

    select pc.*
    from #productcov pc
    where exists (select 1
                  from #productcov pc2
                  where pc2.[group] = pc.[group] and  -- don't know if this is needed
                        pc2.member = pc.member and
                        pc2.product = pc.product and
                        pc.endtime > pc2.starttime and pc.starttime < pc2.endtime
                 ) ;
    

    注意:您可能需要将&gt; 调整为&gt;=&lt; 调整为&lt;=,具体取决于您的重叠规则。

    【讨论】:

    • 我尝试使用存在并使用了与您提供的非常相似的 select 语句,但使用您的 select 语句得到的结果与我自己尝试时得到的结果相同。您提供的 select 语句的结果产生了 20 行,即重复两次的 10 条记录。我试图只获得重叠的 4 条记录。感谢您的帮助。
    【解决方案2】:

    我终于能够为我们的生产数据库自己解决这个审计问题了!我在一个大型查询中使用了多个 Common Table Expressions、Dense_Ranks、Row_Numbers 来解决!稍后将发布测试数据查询的结果。

    with cte as ( 
       select distinct 
       DENSE_RANK() OVER (ORDER BY CONCAT(rtrim([group]),rtrim    (account),rtrim(member), rtrim(product), rtrim([plan]))) AS [Key Count],
       ROW_NUMBER() OVER (PARTITION BY CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])) order by CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])), StartTime) as [Overlap],
       CONCAT(DENSE_RANK() OVER (ORDER BY CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan]))), ROW_NUMBER() OVER (PARTITION BY CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])) order by CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])), StartTime)) as Identifier,
       CONCAT(rtrim([group]),rtrim(account),rtrim(member), rtrim(product), rtrim([plan])) as [Key],
       StartTime as [Eff Date],
       case when EndTime = 0 then '29991231' else EndTime end as [Term Date],
       [group],
       account,
       member,
       product,
       [plan]
    from   #productcov
    where  [group] like 'N%'), 
    
    cte2 as (
       select distinct 
       DENSE_RANK() OVER (ORDER BY CONCAT(rtrim([group]),rtrim(account),rtrim(member), rtrim(product), rtrim([plan]))) AS [Key Count],
       ROW_NUMBER() OVER (PARTITION BY CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])) order by CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])), StartTime) as [Overlap],
       CONCAT(DENSE_RANK() OVER (ORDER BY CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan]))), ROW_NUMBER() OVER (PARTITION BY CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])) order by CONCAT(rtrim([group]),rtrim(account), rtrim(member), rtrim(product), rtrim([plan])), StartTime)) as Identifier,
       CONCAT(rtrim([group]),rtrim(account),rtrim(member), rtrim(product), rtrim([plan])) as [Key],
       StartTime as [Eff Date],
       case when EndTime = 0 then '29991231' else EndTime end as [Term Date],
       [group],
       account,
       member,
       product,
       [plan]
    from   #productcov
    where  [group] like 'N%')
    
    select distinct 
                cte2.[Group], 
                cte2.[Account], 
                cte2.[Member],
                cte2.[Product],
                cte2.[Plan]
    from   cte
    left outer join cte2 on cte.[Key] = cte2.[Key]
    where  (cte2.[Eff Date] between cte.[Eff Date] and cte.[Term Date]
    or      cte2.[Term Date] between cte.[Eff Date] and cte.[Term Date])
    and    cte.[Key Count] = cte2.[Key Count]
    and    cte.[Identifier] <> cte2.[Identifier]
    group by cte2.[Group], cte2.[Account], cte2.[Member], cte2.[Product], cte2.[Plan]
    order by cte2.[Group], cte2.[Account], cte2.[Member], cte2.[Product], cte2.[Plan];
    

    【讨论】:

      猜你喜欢
      • 2018-03-03
      • 2013-10-21
      • 2020-04-24
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2013-10-05
      • 1970-01-01
      • 2018-02-19
      相关资源
      最近更新 更多