2012-09-07 109 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应解决该问题。

相关问题