SQL-соединения и исключения - PullRequest
3 голосов
/ 03 ноября 2010

Принимая запрос как таковой в 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?

Заранее спасибо за любые ответы: -)

EDIT: Для пояснения здесь приводится весь запрос в том виде, в котором он находится на данный момент, если это поможет.

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 ]

3 голосов
/ 03 ноября 2010

Первый более понятен, потому что вам не нужно беспокоиться о несовпадающих строках в 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).

3 голосов
/ 03 ноября 2010

Они не совсем одинаковы, если только StockBarcode.Inactive не обнуляется.

Если StockBarcode.Inactive равен nullable, то первый запрос не будет возвращать никаких сведений для StockBarcodes, где Inactive равен нулю (так как они не соответствуют условию соединения), а второй запрос будет включать их, если они совпадают другие условия соединения - они будут соответствовать условию where.

1 голос
/ 03 ноября 2010

Какой запрос является оптимальным и почему?

Посмотрите на план запроса.

Но я уверен, что 1-е должно быть более производительным, поскольку условие SB.Inactive = 0 может быть охвачено индексом.

Был бы другой случай, если бы я использовал другой движок базы данных, такой как MySql?

Конечно, план выполнения и производительность строго зависят от поставщика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...