【问题标题】:SQL query help, conditional joinSQL查询帮助,条件连接
【发布时间】:2010-09-06 23:06:40
【问题描述】:

这里是 SQL 新手 :)

如果有人感兴趣,这是我的桌子。

啊哈,还不能发图 http://img832.imageshack.us/img832/442/72098588.jpg

我要做的是在日期间隔内查询 tblPatientStats 表(@StartDate,@EndDate) 并将它们相应地分组在winforms的数据网格中。

所以 tblPatientStats 中的每一行要么有一个 RefDoctor 或 RefMode,要么两者都有,或者根本没有。

所以查询应该返回一个表,其中包含来自 tblPatient 的患者姓名、来自 tblRefMode 的 RefMode、来自 tblPatientStats 的 RefDoctor 的名称(Title + FirstName + lastName)和 SessionDate

==> yfrog dot com/0yhi2dj

这是我目前的尝试。

INSERT @Final(Name, Doctor, Mode, SessionDate)
 SELECT DISTINCT (FirstNames + LastName) as Name, 
 (tblRefDoctor.RefDTitle + ' ' + tblRefDoctor.RefDFNames + ' ' + tblRefDoctor.RefDName) AS Doctor, 
 tblRefMode.RefMode AS Mode, SessionDate 

 FROM tblPatientStats, tblPatient
 left outer join tblRefDoctor on (RefDoctor = tblRefDoctor.RefDoctor)
 left outer join tblRefMode on (RefModeID = tblRefMode.RefModeID)
 WHERE
 tblPatientStats.RefDoctor IS NOT NULL or tblPatientStats.RefModeID IS NOT NULL
 AND 
 tblPatient.PatientID = tblPatientStats.PatientID
 AND tblPatientStats.SessionDate between @StartDate AND @EndDate 

我做错了什么?每次查询超时,表很小,每个不到10K记录。

任何帮助将不胜感激。

【问题讨论】:

    标签: sql sql-server database relational-database


    【解决方案1】:

    我怀疑这个问题是因为笛卡尔加入

    tblPatientStats, tblPatient
    

    虽然where 子句中有连接条件,但布尔运算符的优先级存在问题。这是为了Not, And, Or,所以我认为您需要在 'Or' ed 条件周围加上括号。

    原始查询上的WHERE 条件应用括号显示有效的运算符优先级是

     WHERE
     tblPatientStats.RefDoctor IS NOT NULL or 
    
    (tblPatientStats.RefModeID IS NOT NULL 
         AND tblPatient.PatientID = tblPatientStats.PatientID  
         AND tblPatientStats.SessionDate between @StartDate AND @EndDate)
    

    这几乎肯定不是所需的语义,并且可能会带回太多行。

    我已将 tblPatientStatstblPatient 之间的连接条件上移到 JOIN 子句中,并将括号添加到 Or ed 条件中。

     FROM tblPatientStats
     inner join tblPatient on tblPatient.PatientID = tblPatientStats.PatientID
     left outer join tblRefDoctor on RefDoctor = tblRefDoctor.RefDoctor
     left outer join tblRefMode on RefModeID = tblRefMode.RefModeID
     WHERE
     (tblPatientStats.RefDoctor IS NOT NULL or tblPatientStats.RefModeID IS NOT NULL)
     AND tblPatientStats.SessionDate between @StartDate AND @EndDate 
    

    【讨论】:

    • 不应该使用隐含语法或隐含与显式结合的另一个原因。