三个表中的SQL连接问题在不满足条件时返回结果

时间:2017-01-06 22:37:53

标签: sql-server

我正在尝试运行一个查看人员表,约会表和提醒表的查询。

我想只返回至少有一次约会,未来没有约会,并且系统中没有活动提醒的人。

SELECT  p.person_ID
from people p   
WHERE exists (
select 1 from appointments e where e.person_id=p.person_id 
    AND e.appt_kept_ind='Y' )
AND not exists (
   select 1 from appointments s where s.person_id=p.person_id 
   AND CONVERT(DateTime, s.apptdate, 112) > CURRENT_TIMESTAMP))
AND not exists (
   select 1 from reminder re where re.person_id=p.person_id 
   AND  CONVERT(DateTime, re.return_date, 112) > CURRENT_TIMESTAMP )

编辑:在收到反馈后我删除了左连接;我注意到其中一个问题是主动='y'某人可以有一个主动提醒,但提醒可能是过去的,仍然“活跃”所以我更新它也检查他们的提醒日期是否仅在将来并排除这些记录。

编辑:请求架构

Person
   person_id UniqueIdentifier NOT NULL PK
   firstname nvarchar NOT NULL
   lastname nvarchar NOT NULL
   ....

Appointments
   appointment_ID uniqueidentifier NOT NULL PK  
   person_ID uniqueidentifier NOT NULL
   apptdate nvarchar NOT NULL
   apptKept nvarchar (N or Y)

Reminder
    reminder_id uniqueidentifier NOT NULL PK
    person_ID uniqueidentifier NOT NULL
    return_date nvarchar NOT NULL
    Active nvarchar (N or Y)

我遇到了一些问题:返回多个人的结果,如果我需要的所有数据都在人员表中,我甚至需要连接吗?最后,它相当慢。

1 个答案:

答案 0 :(得分:0)

有一些观点可以想到:

  1. 如果某人有多个约会或多个提醒(由于左连接),您会获得其他列;顺便说一句,我不认为有必要在这里加入提醒,因为你没有使用结果。
  2. 在两个左连接后的where-part中使用相关子查询。理论上,每个子查询都会针对此连接返回的每个(可能是重复的)元组进行评估。根据数据,我假设不相关的子查询可能更快。
  3. 尝试以下方法(希望语法正确,因为我无法在没有架构的情况下尝试)。方法是通过准备一个表格appaggr来一次性检查约会,该表格评估每个人person_id最大kept(如果存在任何元组,则必须为Y ),并在同一次运行中评估最新的约会(如果不存在将来的约会,则必须在current_timestamp之前)。加入(注意:没有离开加入)此表到人员表应返回所有已预约且未来任何约会的人。此外,检查提醒被转换为不相关的子查询;如果没有多少人有活动提醒,这应该可以更有效地工作:

    SELECT   p.firstname, p.lastname,  p.person_ID, 
    from people p 
    join (select a.person_id, max(a.kept) as maxkept, max(CONVERT(DateTime, a.apptdate, 112)) as maxdate 
               from appointments a
               group by a.person_id
               having maxkept='Y' and maxdate <= CURRENT_TIMESTAMP) appaggr on p.person_id = appaggr.person_id
    where p.person_id not in (select r.person_id from reminder r where r.active='Y')