WHERE NOT EXISTS 检查和等于“=”检查一起失败但分开工作
WHERE NOT EXISTS check and equals to "=" check fail together but work seperatly
我有一个 INSERT SQL 查询,需要检查该条目是否会导致重复预订,以及 2 个用户(医生和患者)是否隶属于同一诊所。 (发现在场景方面更容易解释),我的 SQL 是:
WITH ins (MedStaffID, PatientID, TimeSlot, AppDate)
AS (SELECT 1, 6, 10, DATEADD(day, 1, CAST(GETDATE() AS DATE)))
INSERT INTO Appointments (MedStaffID, PatientID, TimeSlot, AppDate)
SELECT ins.MedStaffID, ins.PatientID, ins.TimeSlot, ins.AppDate
FROM ins
WHERE
NOT EXISTS
(
SELECT *
FROM Appointments
WHERE (MedStaffID = ins.MedStaffID OR PatientID = ins.PatientID)
AND TimeSlot = TimeSlot
AND AppDate = ins.AppDate
)
AND
(
SELECT Clinic
FROM Users UD
WHERE UD.ID = ins.MedStaffID
)
=
(
SELECT Clinic
FROM Users UD
WHERE UD.ID = ins.PatientID
);
两个 WHERE 检查在没有其他检查的情况下也能正常运行,但是当在一起时总是导致 INSERT 不继续,即使它应该通过两个检查。
示例用户 Table:
ID Clinic Role Forename n'otherstuff
1 1 Doctor Bob Potato
2 1 Patient Jim Cake
3 1 Patient Laura Tart
4 2 Doctor Sally Muffin
5 2 Patient Khaaan Lolly
约会示例Table:
ID MedStaffID PatientID TimeSlot Date
1 1 2 1 *today
2 1 2 2 *today
3 1 3 4 *today
4 4 5 2 *today
因此,如果医生已经在那个时间和日期有预约,那么插入需要防止再次预约医生,对于患者也是如此。
还需要保证医生和病人在同一家诊所。
支票单独完成它们的工作,但我需要它们一起工作,还需要进行另一次检查以确保放置在 "MedStaffID" 字段中的 ID 与具有 [=28= 的用户相关联] "Doctor",但现在我对这两项检查感到困惑。
也许你只是想直接加入?
WITH ins (MedStaffID, PatientID, TimeSlot, AppDate)
AS (SELECT 1, 6, 10, DATEADD(day, 1, CAST(GETDATE() AS DATE)))
INSERT INTO Appointments (MedStaffID, PatientID, TimeSlot, AppDate)
SELECT ins.MedStaffID, ins.PatientID, ins.TimeSlot, ins.AppDate
FROM ins
JOIN Users Staff ON (Staff.ID = ins.MedStaffID)
JOIN Users Patient ON (Patient.ID = ins.PatientID)
WHERE Staff.Clinic = Patient.Clinic
AND NOT EXISTS ( SELECT *
FROM Appointments
WHERE (MedStaffID = ins.MedStaffID OR PatientID = ins.PatientID)
AND TimeSlot = TimeSlot
AND AppDate = ins.AppDate
)
;
我还没有确定问题所在。然而...
在不存在的代码中,不应该:
AND TimeSlot = TimeSlot
成为
AND TimeSlot = ins.TimeSlot
作为优化步骤,ClinicID 检查应该放在第一位。 Where-not-exists 通常是全 table 扫描(或全索引扫描)。如果 table 总是很小,那不是问题。
作为优化步骤,where-not-exists 子句应该 select id,而不是 *。
不应该是这样,但可能是这样,因为我找不到其他任何东西,运算符优先级正在咬你。在您的 ClinicID 检查(整个表达式)周围添加括号。
Explain Query
是你的朋友。
我有一个 INSERT SQL 查询,需要检查该条目是否会导致重复预订,以及 2 个用户(医生和患者)是否隶属于同一诊所。 (发现在场景方面更容易解释),我的 SQL 是:
WITH ins (MedStaffID, PatientID, TimeSlot, AppDate)
AS (SELECT 1, 6, 10, DATEADD(day, 1, CAST(GETDATE() AS DATE)))
INSERT INTO Appointments (MedStaffID, PatientID, TimeSlot, AppDate)
SELECT ins.MedStaffID, ins.PatientID, ins.TimeSlot, ins.AppDate
FROM ins
WHERE
NOT EXISTS
(
SELECT *
FROM Appointments
WHERE (MedStaffID = ins.MedStaffID OR PatientID = ins.PatientID)
AND TimeSlot = TimeSlot
AND AppDate = ins.AppDate
)
AND
(
SELECT Clinic
FROM Users UD
WHERE UD.ID = ins.MedStaffID
)
=
(
SELECT Clinic
FROM Users UD
WHERE UD.ID = ins.PatientID
);
两个 WHERE 检查在没有其他检查的情况下也能正常运行,但是当在一起时总是导致 INSERT 不继续,即使它应该通过两个检查。
示例用户 Table:
ID Clinic Role Forename n'otherstuff
1 1 Doctor Bob Potato
2 1 Patient Jim Cake
3 1 Patient Laura Tart
4 2 Doctor Sally Muffin
5 2 Patient Khaaan Lolly
约会示例Table:
ID MedStaffID PatientID TimeSlot Date
1 1 2 1 *today
2 1 2 2 *today
3 1 3 4 *today
4 4 5 2 *today
因此,如果医生已经在那个时间和日期有预约,那么插入需要防止再次预约医生,对于患者也是如此。
还需要保证医生和病人在同一家诊所。
支票单独完成它们的工作,但我需要它们一起工作,还需要进行另一次检查以确保放置在 "MedStaffID" 字段中的 ID 与具有 [=28= 的用户相关联] "Doctor",但现在我对这两项检查感到困惑。
也许你只是想直接加入?
WITH ins (MedStaffID, PatientID, TimeSlot, AppDate)
AS (SELECT 1, 6, 10, DATEADD(day, 1, CAST(GETDATE() AS DATE)))
INSERT INTO Appointments (MedStaffID, PatientID, TimeSlot, AppDate)
SELECT ins.MedStaffID, ins.PatientID, ins.TimeSlot, ins.AppDate
FROM ins
JOIN Users Staff ON (Staff.ID = ins.MedStaffID)
JOIN Users Patient ON (Patient.ID = ins.PatientID)
WHERE Staff.Clinic = Patient.Clinic
AND NOT EXISTS ( SELECT *
FROM Appointments
WHERE (MedStaffID = ins.MedStaffID OR PatientID = ins.PatientID)
AND TimeSlot = TimeSlot
AND AppDate = ins.AppDate
)
;
我还没有确定问题所在。然而...
在不存在的代码中,不应该:
AND TimeSlot = TimeSlot
成为
AND TimeSlot = ins.TimeSlot
作为优化步骤,ClinicID 检查应该放在第一位。 Where-not-exists 通常是全 table 扫描(或全索引扫描)。如果 table 总是很小,那不是问题。
作为优化步骤,where-not-exists 子句应该 select id,而不是 *。
不应该是这样,但可能是这样,因为我找不到其他任何东西,运算符优先级正在咬你。在您的 ClinicID 检查(整个表达式)周围添加括号。
Explain Query
是你的朋友。