Разница между условием в месте и условием в соединении - PullRequest
2 голосов
/ 10 июля 2009

Может кто-нибудь объяснить, почему следующие два запроса дают разные результаты?

SELECT
    o.*
FROM
    Customer c
LEFT JOIN 
    [Order] o ON o.CustomerID = c.CustomerID AND o.OrderType = 'Cash'
WHERE
    c.Country = 'USA'

SELECT
    o.*
FROM
    Customer c
LEFT JOIN 
    [Order] o ON o.CustomerID = c.CustomerID
WHERE
    c.Country = 'USA'
AND
    o.OrderType = 'Cash'

Спасибо.

Ответы [ 4 ]

5 голосов
/ 10 июля 2009

Первый позволяет ордеру быть НЕДЕЙСТВИТЕЛЬНЫМ, потому что это левое соединение.
Второй нет, так как он проверяет значение o.OrderType после объединения.

Эквивалент будет (при условии, что OrderType не может быть NULL)

SELECT
    o.*
FROM
    Customer c
LEFT JOIN 
    [Order] o ON o.CustomerID = c.CustomerID
WHERE
    c.Country = 'USA'
AND
    (o.OrderType = 'Cash' OR o.OrderType IS NULL)
0 голосов
/ 26 февраля 2013

В первом примере условие фильтрации сначала применяется для фильтрации заказов типа заказа наличными, а затем объединяется с таблицей клиентов.

Во втором примере две таблицы объединяются, а затем применяется фильтрованное условие. Следовательно, результат будет другим.

0 голосов
/ 10 июля 2009
0 голосов
/ 10 июля 2009

Это левое соединение.

В первом случае вы можете получить меньше записей, потому что только один клиент перейдет к условию WHERE, если его заказы отфильтрованы по условию Cash в Join.

Во втором случае пройдет больше пар заказов клиентов, и после фильтров WHERE может остаться больше.

Убедитесь, что вам действительно нужно LEFT JOIN, и если да, то убедитесь, какая из этих двух семантик вам нужна в этом случае.

...