首页 > 解决方案 > NOT IN 条件返回意外结果

问题描述

我们正在尝试创建一份报告,以识别在日程表上没有任何未来预约的活跃患者。活跃的患者将是在过去一年内预约过的人。我的想法是创建一个包含去年见过的所有患者的临时表,然后使用 NOT IN 条件将它们从我的下一个查询中排除。它没有产生预期的结果。

以下查询列出了所有在去年就诊且未取消或未出现的患者。

SELECT Patient_ID
INTO #TempPreviousAppt
FROM Appointments
WHERE Appointment_DateTime > DATEADD(year,-1,GETDATE())
AND Status NOT IN ('X','N')
GROUP BY Patient_ID

这会产生 48,489 个结果

以下查询列出了未来预约的所有患者。

SELECT Patient_ID
INTO #TempFutureAppt
FROM Appointments AS Appt
WHERE Appt.Appointment_DateTime > GETDATE()
AND Status != 'S'
GROUP BY Patient_ID

这会产生 4,683 个结果

当我尝试使用以下查询确定以前看过的患者是否有未来的预约时。

SELECT Patient_ID 
FROM #TempPreviousAppt
WHERE Patient_ID NOT IN
(SELECT ISNULL(Patient_ID ,'')
FROM #TempFutureAppt)

它产生 43,843 个结果。我不确定我错过了什么。查询的逻辑不是“显示所有以前预约但没有未来预约的患者”吗?

标签: sqlsql-server

解决方案


你的文字标准说

活跃的患者将是在过去一年内预约过的人。

但是您的查询表明活跃患者是在过去一年内预约过的人,或者在未来任何时间安排过预约的人:

WHERE Appointment_DateTime > DATEADD(year,-1,GETDATE())

下面的查询假定文本描述,而不是查询描述。鉴于此,EXISTS相关的子查询应该可以让您到达您想要的位置。

SELECT 
   Appt.Patient_ID
  ,Pat.Patient_Number
FROM 
  Appointments AS Appt
JOIN 
  Patients AS Pat 
    ON 
      Appt.Patient_ID = Pat.Patient_ID
WHERE 
  Appt.Appointment_DateTime !< GETDATE()
  AND 
  EXISTS
    (
      SELECT 
        1
      FROM 
        Appointments AS a2
      WHERE
        a2.Patient_ID = Appt.Patient_ID
        AND
        a2.Appointment_DateTime >= DATEADD(year,-1,CAST(GETDATE() AS DATE))
        AND
        a2.Appointment_DateTime < CAST(GETDATE() AS DATE)
      AND 
        a2.Status = 'X' 
        OR 
        a2.Status = 'N'
    )

编辑

抱歉,我一开始并没有想到“肮脏和肮脏”。

设置:

DECLARE @t TABLE
(
  Patient_ID INT,
  Appointment_DateTime DATETIME
);

INSERT @t
VALUES
  (1,'20181001'),
  (1,'20181115'),
  (2,'20171204'),
  (3,'20190101');
  • 患者 1:过去的预约和未来的预约。所以我们不在乎。
  • 患者 2:过去的约会,没有未来的约会。我们关心。
  • 患者 3:只有未来的约会。我们不在乎。

查询去年有过约会的患者(请注意,上面的查询中缺少“GETDATE()”的结束日期。可能或可能无关紧要。不确定)。

SELECT
  Patient_ID
FROM
  @t AS appt
WHERE 
  appt.Appointment_DateTime >= DATEADD(YEAR,-1,CAST(GETDATE() AS DATE))
  AND
  appt.Appointment_DateTime < CAST(GETDATE() AS DATE)

结果:

+------------+
| Patient_ID |
+------------+
|          1 |
|          2 |
+------------+

查询未来预约的患者:

SELECT
  Patient_ID
FROM
  @t AS appt2
WHERE 
  appt2.Appointment_DateTime > CAST(GETDATE() AS DATE)

结果:

+------------+
| Patient_ID |
+------------+
|          1 |
|          3 |
+------------+

查询过去预约但没有未来预约的患者:

SELECT
  Patient_ID
FROM
  @t AS appt
WHERE 
  appt.Appointment_DateTime >= DATEADD(YEAR,-1,CAST(GETDATE() AS DATE))
  AND
  appt.Appointment_DateTime < CAST(GETDATE() AS DATE)
EXCEPT
SELECT
  Patient_ID
FROM
  @t AS appt2
WHERE 
  appt2.Appointment_DateTime > CAST(GETDATE() AS DATE)

结果:

+------------+
| Patient_ID |
+------------+
|          2 |
+------------+

推荐阅读