Внутренний синтаксис SQL - PullRequest
26 голосов
/ 27 декабря 2008

два бита SQL ниже дают тот же результат

SELECT c.name, o.product  
FROM customer c, order o  
WHERE c.id = o.cust_id  
AND o.value = 150  

SELECT c.name, o.product  
FROM customer c  
INNER JOIN order o on c.id = o.cust_id  
WHERE o.value = 150

Я видел оба стиля, используемые в разных компаниях как стандартные. Из того, что я видел, второе - то, что большинство людей рекомендует онлайн. Есть ли реальная причина для этого, кроме стиля? Может ли использование внутреннего соединения иногда иметь лучшую производительность?

Я заметил, что разработчики Ingres и Oracle, как правило, используют первый стиль, тогда как пользователи Microsoft SQL Server обычно используют второй, но это может быть просто совпадением.

Спасибо за понимание, я некоторое время размышлял об этом.

Редактировать: я изменил название с «Внутреннее соединение SQL по сравнению с декартовым продуктом», поскольку использовал неверную терминологию. Спасибо за все ответы до сих пор.

Ответы [ 6 ]

27 голосов
/ 27 декабря 2008

Оба запроса являются внутренними объединениями и эквивалентны. Первый - это более старый метод ведения дел, в то время как использование синтаксиса JOIN стало обычным делом только после введения стандарта SQL-92 (я полагаю, что это в более старых определениях, просто до этого не было особенно широкого применения).

Использование синтаксиса JOIN настоятельно рекомендуется, поскольку оно отделяет логику соединения от логики фильтрации в предложении WHERE. Хотя синтаксис JOIN действительно является синтаксическим сахаром для внутренних объединений, его сила заключается в внешних объединениях, где старый синтаксис * может привести к ситуациям, когда невозможно однозначно описать объединение, а интерпретация зависит от реализации. [ЛЕВЫЙ | RIGHT] Синтаксис JOIN позволяет избежать этих ловушек, и, следовательно, для согласованности использование предложения JOIN предпочтительнее при любых обстоятельствах.

Обратите внимание, что ни один из этих двух примеров не является декартовым произведением. Для этого вы бы использовали либо

SELECT c.name, o.product  
FROM customer c, order o  
WHERE o.value = 150  

или

SELECT c.name, o.product  
FROM customer c  CROSS JOIN order o 
WHERE o.value = 150
6 голосов
/ 27 декабря 2008

Чтобы ответить на часть вашего вопроса, я думаю, что ранние ошибки в синтаксисе JOIN ... ON в Oracle отговаривали пользователей Oracle от этого синтаксиса. Я не думаю, что сейчас есть какие-то особые проблемы.

Они эквивалентны и должны быть проанализированы в одном и том же внутреннем представлении для оптимизации.

4 голосов
/ 27 декабря 2008

Oracle опоздала с поддержкой синтаксиса JOIN ... ON (ANSI) (не раньше Oracle 9), поэтому разработчики Oracle часто не используют его.

Лично я предпочитаю использовать синтаксис ANSI, когда логически ясно, что одна таблица управляет запросом, а другие - это таблицы поиска. Когда таблицы «равны», я склонен использовать декартовой синтаксис.

Производительность не должна отличаться вообще.

4 голосов
/ 27 декабря 2008

На самом деле эти примеры эквивалентны, и ни один из них не является декартовым произведением. Декартово произведение возвращается, когда вы объединяете две таблицы без указания условия соединения, например, в

select *
from t1,t2

Это хорошее обсуждение на Википедии .

3 голосов
/ 29 декабря 2008

Синтаксис JOIN ... ON ... является более поздним дополнением к спецификациям ANSI и ISO для SQL. Синтаксис JOIN ... ON ... обычно предпочтительнее, поскольку он 1) перемещает критерии объединения из предложения WHERE, делая предложение WHERE только для фильтрации, и 2) делает его более очевидным, если вы создаете страшный декартовой продукт, поскольку каждый Присоединение должно сопровождаться хотя бы одним предложением ON. Если в предложении WHERE все критерии объединения просто указаны AND, это не так очевидно, если один или несколько пропущены.

3 голосов
/ 27 декабря 2008

Оба запроса выполняют внутреннее соединение, только разный синтаксис.

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