SQL Server查询:SELECT 1 WHERE EXISTS vs SELECT TOP 1 1

时间:2010-01-19 05:41:16

标签: sql sql-server sql-server-2005 tsql query-optimization

我需要提供一个标志 - 如果条件不满足则为0,如果是,则为1 - 我可以用两种不同的方式进行:

获取员工ID,名称,如果其他人在子订单中,则为1 - 否则为0:

SELECT e.ID
     , e.Name
     , ISNULL ( ( SELECT TOP 1 1 FROM Employee se WHERE se.ManagerID = e.ID ) , 0 ) AS HasSubordinates 
  FROM Employee e

SELECT e.ID
     , e.Name
     , ISNULL ( ( SELECT 1 WHERE EXISTS ( SELECT * FROM Employee se WHERE se.ManagerID = e.ID ) ) , 0 ) AS HasSubordinates 
  FROM Employee e

您会选择哪个版本?为什么?


更新1


这个怎么样?

SELECT o.ID
     , o.Name
     , o.StartDate
     , o.EndDate
     , ISNULL ( ( SELECT TOP 1 1 FROM changes c WHERE c.ChangeDate BETWEEN o.StartDate AND o.EndDate ) , 0 ) AS IsChanged
  FROM Orders o

SELECT o.ID
     , o.Name
     , o.StartDate
     , o.EndDate
     , ISNULL ( ( SELECT 1 WHERE EXISTS ( SELECT * FROM changes c WHERE c.ChangeDate BETWEEN o.StartDate AND o.EndDate ) ), 0 ) AS IsChanged
  FROM Orders o

2 个答案:

答案 0 :(得分:8)

我也不会使用:

   SELECT t.id,
          t.name,
          CASE WHEN x.managerid IS NULL THEN 0 ELSE 1 END AS HasSubordinates 
     FROM EMPLOYEE t
LEFT JOIN (SELECT DISTINCT 
                  e.managerid
             FROM EMPLOYEE e) x ON x.managerid = t.id

...因为SELECT子句中的相关SELECTS很糟糕 - 它们不会缩放,因为它们会为返回的每一行执行。这意味着您拥有的行越多,相关SELECT的调用次数就越多。

答案 1 :(得分:2)

我也不会......

当你在select语句中有一个subselect时,原因是(这是我所知道的),对于返回的每一行,该subselect将被执行一次。因此,如果主查询返回100行,则实际上将运行101个查询。当您使用联接时,您只需要执行一个需要将左侧和右侧匹配的查询。请注意,如果您在ManagerId上有索引,这将有所帮助。

尝试这样的事情:

SELECT e.ID,
       e.Name,
       COUNT(se.ID) AS TotalStaff
FROM    Employee e 
        LEFT JOIN Employee se 
                ON se.ManagerID = e.ID
GROUP BY e.ID, e.Name 

这与我返回的总数略有不同,而不仅仅是0 | 1,但如果你需要1 | 0,那很容易改变......

如果有帮助,请告诉我