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
                 )
;

我还没有确定问题所在。然而...

  1. 在不存在的代码中,不应该:

    AND TimeSlot = TimeSlot
    

成为

    AND TimeSlot = ins.TimeSlot 
  1. 作为优化步骤,ClinicID 检查应该放在第一位。 Where-not-exists 通常是全 table 扫描(或全索引扫描)。如果 table 总是很小,那不是问题。

  2. 作为优化步骤,where-not-exists 子句应该 select id,而不是 *。

  3. 不应该是这样,但可能是这样,因为我找不到其他任何东西,运算符优先级正在咬你。在您的 ClinicID 检查(整个表达式)周围添加括号。

  4. Explain Query是你的朋友。