【问题标题】:WHERE NOT EXISTS check and equals to "=" check fail together but work seperatlyWHERE NOT EXISTS 检查和等于“=”检查一起失败,但单独工作
【发布时间】:2015-07-21 08:34:28
【问题描述】:

我有一个 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 无法继续。

示例用户表:

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

示例预约表:

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 与具有“角色”“医生”的用户相关联,但是现在我被这两张支票难住了。

【问题讨论】:

    标签: sql sql-server-2008 where not-exists


    【解决方案1】:

    也许您只是想直接加入?

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

    【讨论】:

    • 啊,谢谢,这行得通,没想到这一点,你知道为什么像我一样设置它们不起作用吗,很好奇。
    【解决方案2】:

    我还没有确定问题所在。不过……

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

      AND TimeSlot = TimeSlot
      

    成为

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

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

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

    4. Explain Query 是你的朋友。

    【讨论】:

      猜你喜欢
      • 2017-03-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-19
      相关资源
      最近更新 更多