Sql 未处于返回意外结果的状态
我们正在尝试创建一份报告,以确定那些没有任何未来预约的活动患者。活跃患者是指在过去一年内预约的患者。我的想法是创建一个临时表,其中包含去年内看到的所有患者,然后使用NOT IN CONDICTION将他们从我的下一个查询中排除。它没有产生预期的结果 下面的查询列出了去年就诊的所有患者,这些患者不是被取消或未就诊 这将产生48489个结果 以下查询列出了未来预约的所有患者 这将产生4683个结果 当我尝试使用以下查询确定以前见过的患者是否有未来的预约时Sql 未处于返回意外结果的状态,sql,sql-server,Sql,Sql Server,我们正在尝试创建一份报告,以确定那些没有任何未来预约的活动患者。活跃患者是指在过去一年内预约的患者。我的想法是创建一个临时表,其中包含去年内看到的所有患者,然后使用NOT IN CONDICTION将他们从我的下一个查询中排除。它没有产生预期的结果 下面的查询列出了去年就诊的所有患者,这些患者不是被取消或未就诊 这将产生48489个结果 以下查询列出了未来预约的所有患者 这将产生4683个结果 当我尝试使用以下查询确定以前见过的患者是否有未来的预约时 它产生了43843个结果。我不确定我错过了什
它产生了43843个结果。我不确定我错过了什么。查询的逻辑是否不显示所有以前预约但没有未来预约的患者?您不需要公共表表达式的临时表,您做的是相同的工作
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
但是从您的查询中,我明白了为什么您不能在Appt.Appointment\u DateTime
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'
)
患者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)
查询未来预约的患者:
SELECT
Patient_ID
FROM
@t AS appt2
WHERE
appt2.Appointment_DateTime > CAST(GETDATE() AS DATE)
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 |
+------------+
| 1 |
| 2 |
+------------+
+------------+
| Patient_ID |
+------------+
| 1 |
| 3 |
+------------+
+------------+
| Patient_ID |
+------------+
| 2 |
+------------+
查询有过去预约但没有未来预约的患者:
SELECT
Patient_ID
FROM
@t AS appt2
WHERE
appt2.Appointment_DateTime > CAST(GETDATE() AS DATE)
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)
当子查询返回的任何值为NULL时,NOT IN具有异常行为。在这种情况下,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);
我还要指出>=比 由于您的问题,请尝试左键连接,例如:
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
如果您提供soma示例数据,我可以测试代码。不在select*。。。。sql server语法无效。选择后需要一个字段名,该查询不应运行。请更改查询或dbms标记。此处不需要临时表,您可以在实际查询中使用CTE或子查询。@GeorgeMenoutis-in select*。。。。如果内表只有一列,你每天都会学到新东西!thanksI以前做过一个子查询,但当它也产生了零结果时,我使用了临时表。最后,我可能只是走错了方向。出于某种原因,我仍然没有得到任何结果。不可能在过去一年内看到的每个患者都已经安排了另一次预约。我一定错过了什么-/@GMR you condition Appt.Appointment\u DateTime
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);
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