Нечетный INNER JOIN синтаксис и инкапсуляция - PullRequest
6 голосов
/ 09 ноября 2011

Я обычно довольно хорошо разбираюсь в JOINS, но это ново.

Предположим, что три таблицы (классический случай двух таблиц и одна третья, таблица компоновщика):

Customer  Product  Transaction
--------  -------  -----------
ID        ID       CustomerID
Name      Desc     ProductID
          Cost     Date

(Упрощенно специально, я не могу воспроизвести реальную структуру, это не мой код.)

Обычно, чтобы получить таблицу «кто что купил, когда», я бы сделал это:

SELECT Customer.Name, Product.Desc, Transaction.Date
FROM Product
INNER JOIN Transaction ON Transaction.ProductID = Product.ID
INNER JOIN Customer ON Transaction.CustomerID = Customer.ID

Но мне подарили это:

SELECT Customer.Name, Product.Desc, Transaction.Date
FROM Product
INNER JOIN ( Transaction
      INNER JOIN Customer ON Transaction.CustomerID = Customer.ID)
ON Transaction.ProductID = Product.ID

Что это? Просто другой синтаксис или трюк с производительностью?

(Это на SQLServer, FYI, но предположительно это может быть применено к другим ...)

1 Ответ

6 голосов
/ 09 ноября 2011

Скобки не меняют семантику. Позиция предложения ON управляет порядком логической обработки объединений.

Первый запрос

SELECT Customer.Name,
       Product.Desc,
       Transaction.Date
FROM   Product
       INNER JOIN Transaction
         ON Transaction.ProductID = Product.ID
       INNER JOIN Customer
         ON Transaction.CustomerID = Customer.ID 

Второй запрос

(лишние скобки удалены)

SELECT Customer.Name,
       Product.Desc,
       Transaction.Date
FROM   Product
       INNER JOIN Transaction
                  INNER JOIN Customer
                    ON Transaction.CustomerID = Customer.ID
         ON Transaction.ProductID = Product.ID 

Итак, логически в вашем первом примере сначала происходит соединение на Transaction, Product, а затем виртуальная таблица, полученная в результате этого, на Customer, тогда как во втором примере соединение на Transaction, Customer происходит первым затем виртуальная таблица, полученная в результате этого, присоединяется к Product

Это только логически, и поскольку внутренние объединения являются ассоциативными и коммутативными, это, скорее всего, не будет иметь никакого значения для плана выполнения (если вы не добавите OPTION (FORCE ORDER) к запросу), но это может сделать для внешних объединений.

Это , которое здесь описывает Ицик Бен Ган , но в статье есть ряд неточностей, см. Также последующее письмо Любора Коллара .

...