SQL连接和排除

时间:2010-11-03 03:39:18

标签: sql sql-server performance tsql

假设在T-SQL中进行查询。

   SELECT *  
     FROM Stock S    
LEFT JOIN StockBarcode SB ON SB.StockID = S.StockID
                         AND SB.ShopID = @ShopID 
                         AND SB.Inactive = 0    
LEFT JOIN StockBarcode SB1 ON SB1.StockID = S.StockID
                          AND SB1.ShopID = 0 
                          AND SB1.Inactive = 0    
    WHERE S.StockID = @StockID

我的理解是我可以像这样重写查询

   SELECT * 
     FROM Stock S    
LEFT JOIN StockBarcode SB ON S.StockID = SB.StockID 
                         AND SB.ShopID = @ShopID    
LEFT JOIN StockBarcode SB1 ON S.StockID = SB1.StockID 
                          AND SB1.ShopID = 0     
    WHERE S.StockID = @StockID 
      AND ISNULL(SB.Inactive, 0) = 0 
      AND ISNULL(SB1.Inactive, 0) = 0

......结果会是一样的。 (如果我错了,请纠正我) 哪个是最佳查询?为什么?如果我使用另一个数据库引擎,如MySql,情况会不同吗?

提前感谢任何答案: - )

修改 为了澄清,这里是整个查询,如果这将有所帮助。

SELECT 
    SSCLRU.SupplierCode,  
    S.[Description],
    S.TaxRate AS GSTRate,
    ISNULL(ISNULL(SB.PackPrice, SB1.PackPrice), S.RRP) AS Price,
    ISNULL(SB.PackSize, SB1.PackSize) AS Quantity,
    ISNULL(SB.SalePrice, SB1.SalePrice) AS SalePrice,
    ISNULL(SB.SaleDateFrom, SB1.SaleDateFrom) AS SalePriceStartDate,
    ISNULL(SB.SaleDateTo, SB1.SaleDateTo) AS SalePriceEndDate
FROM Stock S

LEFT JOIN StockSupplierCodePreferredLastReceivedUnique SSCLRU ON
S.StockID = SSCLRU.StockID

LEFT JOIN StockBarcode SB ON
S.StockID = SB.StockID AND
SB.ShopID = @ShopID AND
SB.Inactive = 0

LEFT JOIN StockBarcode SB1 ON
S.StockID = SB1.StockID AND
SB1.ShopID = 0 AND
SB1.Inactive = 0

WHERE S.StockID = @StockID 

3 个答案:

答案 0 :(得分:3)

第一个更清楚,因为您不必担心WHERE中的不匹配行

但是,我可能会使用此构造来完全分离连接和过滤条件

FROM
   Stock S
   LEFT JOIN
   StockSupplierCodePreferredLastReceivedUnique SSCLRU ON S.StockID = SSCLRU.StockID

   LEFT JOIN
   (
    SELECT StockID, ...
    FROM StockBarcode
    WHERE ShopID = @ShopID AND Inactive = 0
   ) SB ON S.StockID = SB.StockID

   LEFT JOIN
   (
    SELECT StockID, ...
    FROM StockBarcode
    WHERE ShopID = 0 AND Inactive = 0
   ) SB1 ON S.StockID = SB1.StockID
WHERE
   S.StockID = @StockID 

派生表也可以推入CTE(或2)。

答案 1 :(得分:3)

除非StockBarcode.Inactive不可为空,否则它们相当相同。

如果StockBarcode.Inactive 可以为空,那么第一个查询将不会返回StockBarcodes的任何详细信息,其中Inactive为null(因为它们未通过连接条件),而第二个查询将包含它们匹配其他加入条件 - 它们将匹配where条件。

答案 2 :(得分:1)

  

哪个是最佳查询?为什么?

查看查询计划。

但是我敢打赌第一个应该更高效,因为SB.Inactive = 0条件可以被索引覆盖。

  

如果我使用其他数据库引擎,例如MySql,情况会不同吗?

当然,执行计划和性能严格依赖于供应商。