我们正在尝试创建一个报告,以识别计划中没有任何未来约会的活跃患者。活跃的患者将是过去一年内约好的患者。我的想法是创建一个包含所有在过去一年内就诊的患者的临时表,然后使用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个结果。我不确定我缺少什么。查询的逻辑是否不是“显示所有先前有约会但没有未来约会的患者”?
答案 0 :(得分:1)
您的文字标准说
活跃的患者将是过去一年内预约的患者。
但是您的查询表明活动的患者是在过去一年内已预约的患者,或在将来的任何时间安排的患者:
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');
查询去年预约的患者(请注意,结束日期为“ 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 |
+------------+
答案 1 :(得分:0)
您不需要通过公用表表达式执行临时表,就可以完成相同的工作
with cte1 as
(
SELECT Patient_ID
FROM Appointments
WHERE year(Appointment_DateTime)= year(getdate())-1 -- will last year records
AND Status = 'X' OR Status = 'N'
), cte2 as
(
SELECT Appt.Patient_ID, Pat.Patient_Number
FROM Appointments AS Appt
JOIN Patients AS Pat ON Appt.Patient_ID = Pat.Patient_ID
WHERE Year(Appt.Appointment_DateTime)>year(getdate())-1 -- will pick except last year
AND Appt.Patient_ID NOT IN (SELECT Patient_ID FROM cte1)
) select * from cte2
使用左联接可以完成相同的任务
with cte1 as
(
SELECT Patient_ID
FROM Appointments
WHERE Year(Appointment_DateTime)= year(getdate())-1 --this will pick last year data
AND Status = 'X' OR Status = 'N'
), cte2 as
(
SELECT Appt.Patient_ID, Pat.Patient_Number
FROM Appointments AS Appt
JOIN Patients AS Pat ON Appt.Patient_ID = Pat.Patient_ID
WHERE year(Appt.Appointment_DateTime) > year(getdate())-1
) select cte2.*
from cte2 left join cte1 on cte2.Patient_ID=cte1.Patient_ID
where cte1.Patient_ID is null
但是从您的查询中我明白了为什么您没有获取数据WHERE Appt.Appointment_DateTime < GETDATE()
的原因,您必须更改此条件
答案 2 :(得分:0)
NOT IN
时, NULL
具有异常的行为。在这种情况下,NOT IN
返回完全没有行。我认为这就是您所看到的行为。
由于以下原因,我强烈建议始终使用NOT EXISTS
而不是NOT IN
:
SELECT Appt.Patient_ID, Pat.Patient_Number
FROM Appointments Appt JOIN
Patients Pat
ON Appt.Patient_ID = Pat.Patient_ID
WHERE Appt.Appointment_DateTime !< GETDATE() AND
NOT EXISTS (SELECT 1 FROM #TempTableG t WHERE t.Patient_ID = Appt.Patient_ID);
我还要指出,>=
比!<
更为普遍。
答案 3 :(得分:0)
由于您的问题,请尝试使用LEFT JOIN,例如:
SELECT Appt.Patient_ID, Pat.Patient_Number
FROM Appointments AS Appt
LEFT JOIN (
SELECT Patient_ID
FROM Appointments
WHERE Appointment_DateTime > DATEADD(year,-1,GETDATE())
AND Status = 'X' OR Status = 'N'
GROUP BY Patient_ID
) AS Pat
ON Appt.Patient_ID = Pat.Patient_ID
WHERE Pat.Patient_ID IS NULL
如果您提供体样本数据,我可以测试代码。