В чем разница между предложением where и предложением, когда таблица покидает соединение? - PullRequest
19 голосов
/ 29 ноября 2011

SQL1:

select t1.f1,t2.f2 
from t1 
   left join t2 on t1.f1 = t2.f2 and t1.f2=1 and t1.f3=0 

SQL2:

select t1.f1,t2.f2 
from t1 
  left join t2 on t1.f1 = t2.f2 
where t1.f2=1 and t1.f3=0

Разница в том, где и в предложении, есть ли тот же результат возврата? а какая разница? СУБД запускает их таким же образом? спасибо.

Ответы [ 5 ]

24 голосов
/ 29 ноября 2011

Предложение where применяется ко всему набору результатов;on clause применяется только к рассматриваемому соединению.

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

Однако, если бы вы включили условие в значение в таблице на стороне соединения external , это имело бы существенное значение.

Вы можете получить больше по этой ссылке: http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause

Например:

select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 and t2.f4=1

select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 where t2.f4=1

- делать разные вещи - первый оставит присоединиться к записи t2, где f4равен 1, тогда как последний фактически превратился во внутреннее соединение с t2.

8 голосов
/ 29 ноября 2011

Первый запрос выполняется быстрее, чем второй, так как условие соединения более специфично, чем второе: нет смысла возвращать записи, которые вы будете фильтровать с помощью предложения where (было бы лучше не возвращать их приall-query1)

В любом случае, это действительно зависит от оптимизатора запросов.

посмотрите на следующее:

Является ли JOIN быстрее, чем WHERE?

2 голосов
/ 19 апреля 2018

Два запроса НЕ идентичны.

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

В вашем случае, для SQL 1 фильтр условий LEFT JOIN включается справа, но левая сторона всегда возвращается перед любой фильтрацией WHERE. Поскольку нет условий WHERE, все t1 всегда возвращается.

В SQL 2 условия LEFT JOIN фильтруют некоторые результаты, отображаемые справа, но снова возвращается все t1. Но на этот раз условия WHERE могут отфильтровать некоторые записи t1.

INSERT INTO `t1` (`f1`,`f2`,`f3`) VALUES (1,1,1); INSERT INTO `t2` (`f3`) VALUES (1);

Поскольку они указывают на различную логику, запрос должен быть написан на основе этого, и это дает нам большую силу и гибкость.

INNER JOIN, однако, возвращает тот же результат, так что да, проверьте оптимизатор.

2 голосов
/ 29 ноября 2011

Реляционная алгебра обеспечивает взаимозаменяемость предикатов в предложении WHERE и INNER JOIN, поэтому даже запросы INNER JOIN с предложениями WHERE могут иметь предикаты, переупорядоченные оптимизатором, чтобы они могли быть уже исключены в процессе JOIN.*

Я рекомендую вам писать запросы как можно более удобным для чтения способом.

Иногда это включает в себя создание ВНУТРЕННЕГО СОЕДИНЕНИЯ относительно «неполным» и помещение некоторых критериев в WHERE просто для создания списков фильтрации.критерии легче поддерживать.

Вы можете получить больше по этой ссылке: http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause

Например, вместо:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Запись:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Но это зависит, конечно.

2 голосов
/ 29 ноября 2011

1)

SQL1: select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 **and** t1.f2=1 and t1.f3=0 

В этом парсер будет проверять каждую строку t1 с каждой строкой t2 с этими 3 условиями.Получение более быстрого результата.

2) SQL2: select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 **where** t1.f2=1 and t1.f3=0

В этом случае объединение принимает только 1-е условие, а затем результат, полученный в результате объединения, фильтруется с этими 2 условиями.И займет больше времени, чем 1-й запрос.

Вы можете получить больше по этой ссылке: http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause

...