2010-11-03 36 views
3

在T-SQL中假设一个查询。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 
+1

第一个看起来会快一点,但是如果你想要真正的统计数据......看一下剖析器跟踪和执行计划 – 2010-11-03 06:33:49

回答

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

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

看看查询计划。

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

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

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

3

他们不是相当是一样的,除非StockBarcode.Inactive不可为空。

如果StockBarcode.Inactive 空,那么第一个查询将不会返回StockBarcodes任何细节,其中无效为空(因为它们不能连接条件),而第二个查询将包括他们,如果他们符合其他加盟条件 - 他们将匹配where条件。

+0

是的,这是我的一个疏忽...... Inactive事实上可以为空... – 2010-11-04 01:47:57