当from子句中的表为列时,简化where子句

时间:2016-05-02 15:46:07

标签: sql sql-server sql-server-2008

我想了解是否有更有效的方法来编写以下查询:

SELECT * 
FROM   requests srp 
       INNER JOIN surgeons rpsur 
               ON rpsur.id = srp.surgeon_id 
       LEFT OUTER JOIN #usersurgeons usersurgeons 
                    ON usersurgeons.surgeon_id = srp.surgeon_id 
       LEFT OUTER JOIN surgeons LOsurgeons 
                    ON usersurgeons.surgeon_id = LOsurgeons.id 
       LEFT OUTER JOIN provsurgeons LOprovsurgeons 
                    ON LOprovsurgeons.id = LOsurgeons.provsurgeon_id 
       INNER JOIN #selectedsurgeons up 
               ON up.surgeon_id = rpsur.id 
       LEFT OUTER JOIN provsurgeons ps 
                    ON ps.id = rpsur.provsurgeon_id 
WHERE  rpsur.isprimary = 0 
       AND usersurgeons.isprimary = 0 
       AND LOsurgeons.isprimary = 0 
       AND LOprovsurgeons.isprimary = 0 
       AND up.isprimary = 0 
       AND ps.isprimary = 0 

我对这里的where子句不满意,是否有更专业的方式来编写它,而不是将子句添加到连接行(例如on xx.id = yy.id and xx.isPrimary=0)??

2 个答案:

答案 0 :(得分:2)

仅从这个查询来看,可以说的事情并不多。您应该考虑添加更多上下文(如何将数据导入这些临时表和%外科医生表的结构):

1)Select *几乎不可能使用任何索引,并在最终结果中提供了很多列(Requests.*surgeons.*Provsurgeons.*等。只返回您需要的列。

2)如果在您的查询中经常执行isPrimary = 0过滤(不仅仅是这个过滤),您可以考虑创建一个视图来获取由isPrimary = 0过滤的数据。 vwSurgeonsvwProvsurgeons。然后,您可以直接加入视图而不是表格。

3)[已在评论中提及]任何排除NULL ed表的OUTER JOIN值的条件都会将OUTER转换为INNER

答案 1 :(得分:0)

不使用连接所有表并在末尾使用where子句,而是仅使用带有筛选记录的派生表。这样您的查询性能会更好。

SELECT * FROM requests srp INNER JOIN surgeons rpsur ON rpsur.id = srp.surgeon_id LEFT OUTER JOIN ( SELECT * FROM #usersurgeons WHERE isprimary = 0 )usersurgeons ON usersurgeons.surgeon_id = srp.surgeon_id LEFT OUTER JOIN ( SELECT * FROM surgeons WHERE isprimary = 0 )LOsurgeons ON usersurgeons.surgeon_id = LOsurgeons.id LEFT OUTER JOIN ( SELECT * FROM provsurgeons WHERE isprimary = 0 )LOprovsurgeons ON LOprovsurgeons.id = LOsurgeons.provsurgeon_id INNER JOIN ( SELECT * FROM #selectedsurgeons WHERE isprimary = 0 )up ON up.surgeon_id = rpsur.id LEFT OUTER JOIN ( SELECT * FROM provsurgeons WHERE isprimary = 0 ) ps ON ps.id = rpsur.provsurgeon_id WHERE rpsur.isprimary = 0