嵌套查询的时间重叠

问题描述

根据当前架构,我被要求查找

Testing

-未经测试并暴露于某种传染病的人 -不要列出任何人两次,也不要列出已知的病人 -曝光=位于同一位置,并且时间重叠(为简单起见,无需重叠时间)

在下面的查询中,我找到了答案,但我无法删除“积极”的人,因为我查询的第二部分(即时间流逝)取决于第一部分,即积极的人去相同地点的时间。 / p>

select * from (
select disTINCT person.PersonID,Register.LociD,Register.Checkin,Register.CheckOut
from person 
join Register on Person.PersonID = Register.PersonID 
join testing on person.PersonID  = testing.PersonID
where testing.Results is 'Positive' ) a 
join (
SELECT disTINCT Person.PersonID,Register.CheckOut
from person join Register on Person.PersonID = Register.PersonID 
where person.PersonID  
not in (SELECT disTINCT testing.PersonID from testing)) b on a.LociD = b.LociD 
and b.checkin >= a.CheckIn and b.CheckIn <= a.CheckOut

所以我的问题是,此查询仅需要显示第二部分结果的结果需要做哪些修改

我认为第一部分是

select * from (
select disTINCT person.PersonID,Register.CheckOut
from person 
join Register on Person.PersonID = Register.PersonID 
join testing on person.PersonID  = testing.PersonID
where testing.Results is 'Positive' ) a 

第二部分是

join (
SELECT disTINCT Person.PersonID,Register.CheckOut
from person join Register on Person.PersonID = Register.PersonID 
where person.PersonID  
not in (SELECT disTINCT testing.PersonID from testing)) b on a.LociD = b.LociD 
and b.checkin >= a.CheckIn and b.CheckIn <= a.CheckOut

解决方法

这是一个复杂的查询。因为您不希望重复,所以我建议仅使用exists对外部查询使用persons

让人们同时在同一地方的想法是在register上使用位置和时间重叠进行自我连接。我认为这是查询中最复杂的部分。剩下的就是检查一个人是否是积极的:

select p.*
from person p 
where not exists (select 1
                  from testing t
                  where t.personid = p.personId and t.results = 'positive'
                 ) and
      exists (select 1
              from register r1 join
                   register r2
                   on r1.locid = r2.locid and
                      r1.checkin < r2.checkout and
                      r2.checkout > r1.checkin join
                   testing t2
                   on r2.personid = t2.personid and
                      t2.results = 'positive' and
                      t2.timestamp < r2.checkout
              where r1.personid = p.personid
             );

时间安排有点棘手,但我认为时间安排是有道理的。有人需要在同一个地方测试之前。当然,如果没有时间限制,您可以删除t2.timestamp < r2.checkout

,

出于可读性考虑,您可以创建CTE,如下所示:

with
  -- returns all the untested persons
  untested as (select p.* from person p left join testing t on t.personid = p.personid where t.testingid is null),--  returns all the infected persons
  infected as (select * from testing where results = 'Positive'),-- returns all the locids that infected persons visited and the start and dates of these visits
  loc_positive as (
    select r.locid,i.timestamp startdate,r.checkout enddate 
    from register r inner join infected i 
    on i.personid = r.personid and i.timestamp between r.checkin and r.checkout
  )
-- returns the distinct untested persons that visited the same locids with persons tested positive at the same time after they were tested 
select distinct u.*
from untested u 
inner join register r on r.personid = u.personid
inner join loc_positive lp on lp.locid = r.locid 
where lp.startdate <= r.checkout and lp.enddate >= r.checkin
,

此答案的解决方案是在第一行中为星标添加唯一名称和列名称。

select DISTINCT unt.PersonID from (
select  person.PersonID,Register.LocID,Register.Checkin,Register.CheckOut
from person join Register on Person.PersonID = Register.PersonID join testing on person.PersonID  = testing.PersonID
where testing.Results is 'Positive' ) pos
join (
SELECT Person.PersonID,Register.CheckOut
from person join Register on Person.PersonID = Register.PersonID where person.PersonID  
not in (SELECT  testing.PersonID from testing)) unt on pos.LocID = unt.LocID 
and unt.checkin >= pos.CheckIn and unt.CheckIn <= pos.CheckOut;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...