2012-09-07 149 views
1

我的SQL有點生疏,只是好奇,如果有更好的方式來做這個WHERE子句?假設有一種方法,我敢肯定有一種方法。它的運行速度很快,但我不喜歡它,並想知道它是否可以改進。有沒有更好的方法來做到這一點?

SELECT DISTINCT p.firstname    , 
      p.middlename    , 
      p.lastname    , 
      p.gender     , 
      p.dob     , 
      p.id  AS patientid , 
      pr.id  AS practiceid , 
      pr.[name] AS practicename, 
      pr.parentaco    , 
      pp.encounterdate 
FROM   ((aco.patients_practices patients_practices 
      LEFT OUTER JOIN aco.patients p 
      ON    (
          patients_practices.patientid = p.id 
          ) 
      ) 
      LEFT OUTER JOIN aco.practices pr 
      ON    (
          patients_practices.practiceid = pr.id 
          ) 
      ) 
      INNER JOIN aco.patientpreferences pp 
      ON    (
          pp.patientid = p.id 
          ) 
WHERE   (
          pr.parentaco = 
          (SELECT parentaco 
          FROM aco.practices 
          WHERE master_companyid = 763 
          ) 
      OR    pr.id = 
          (SELECT parentaco 
          FROM aco.practices 
          WHERE master_companyid = 763 
          ) 
      ) 
AND    pp.encounterdate IS NOT NULL 
+0

'master_companyid'是否有唯一的約束? – Kash

+0

否,因爲它可以有很多孩子。這是Master_Company表中的FK。 – dbinott

+1

您對'WHERE'子句中'pr'的引用有效地將'LEFT OUTER'連接轉換爲'INNER'連接。尾隨的'INNER'加入也沒有幫助。 – HABO

回答

5

您可以先從您的子查詢中獲取值並將其放入變量中。

DECLARE @P INT 

SELECT @P = parentaco 
FROM aco.practices 
WHERE master_companyid = 763 

爲什麼您使用的是相同的條件下使用變量在查詢

WHERE (pr.parentaco = @P or pr.id = @P) AND 
     pp.encounterdate IS NOT NULL 
0

兩次在這裏的條件?你是否第二次使用不同的ID?

爲什麼不只是加入反對練習表,然後只是在那裏做一個條件,沒有子選擇?

+0

這不完全相同。其中一個是查看另一個id的parentaco。 parentaco是一個自我引用的id父母子女關係。 – dbinott

0

這可能不是100%,但希望能指導你去正確的條件。

SELECT DISTINCT p.firstname   , 
      p.middlename    , 
      p.lastname    , 
      p.gender     , 
      p.dob     , 
      p.id  AS patientid , 
      pr.id  AS practiceid , 
      pr.[name] AS practicename, 
      pr.parentaco    , 
      pp.encounterdate 
FROM  aco.patients_practices pp 
      LEFT OUTER JOIN aco.patients p 
       ON pp.patientid = p.id 
      LEFT OUTER JOIN aco.practices pr 
       ON pp.practiceid = pr.id 
       AND (pr.parentaco = pp.parentco or pr.id = pp.parentco) 
WHERE pp.encounterdate IS NOT NULL 
     AND pp.master_companyid = 763 
1

LEFT OUTER JOIN s的有效轉換成INNER JOIN原因可能會在它們的WHERE子句中引用的方式。我想你會發現,這在邏輯上是等價的:

select distinct p.firstname, p.middlename, p.lastname, 
    p.gender, p.dob, p.id as patientid, 
    pr.id as practiceid, pr.[name] as practicename, pr.parentaco, 
    pp.encounterdate 
    from aco.patients_practices as patients_practices inner join 
    aco.patients as p on p.id = patients_practices.patientid inner join 
    aco.practices as pr on pr.id = patients_practices.practiceid inner join 
    aco.patientpreferences as pp on pp.patientid = p.id 
    where pp.encounterdate is not null and 
    (pr.parentaco = (select parentaco from aco.practices where master_companyid = 763) or 
    pr.id = (select parentaco from aco.practices where master_companyid = 763)) 

關於WHERE子句中的子查詢重複:查詢優化器應該認識到重複和相應的處理。您可以通過檢查執行計劃來確認。使用Mikael Eriksson的建議在變量中捕獲parentaco應解決該問題。

相關問題