Где разместить условные выражения в запросах ANSI-синтаксиса SQL - PullRequest
3 голосов
/ 09 июня 2010

В чем разница между этими двумя запросами?Я не поддавался прыжкам на ANSI-синтаксисе, потому что я не смог распутать различные синтаксические неоднозначности.

Is 1) возвращает продукт объединения и только затем отфильтровывает те объединенные записи,вес> = 500?И 2) отфильтровывает ли те, которые были до объединения?

Является ли 2 плохой синтаксис?Зачем мне это использовать?

1:

SELECT SOMETHING
FROM FOO
INNER JOIN BAR
ON FOO.NAME = BAR.NAME
WHERE BAR.WEIGHT < 500

2:

SELECT SOMETHING
FROM FOO
INNER JOIN BAR
ON FOO.NAME = BAR.NAME AND BAR.WEIGHT < 500

Ответы [ 6 ]

5 голосов
/ 09 июня 2010

" Является ли 1) возвратом продукта объединения и только затем отфильтровывает те объединенные записи, которые имеют вес> = 500? И составляет 2) отфильтровывает записи до объединения ?"

true, за исключением того, что логически , 2) применяет фильтр как часть объединения, а не до присоединиться. Однако для внутреннего соединения это различие не повлияет на конечный набор результатов запроса. Для Внешних соединений это различие может изменить результаты.

ПРИМЕЧАНИЕ : Использование слова логически (говоря о том, что это последовательность, в которой процессор запросов логически выполняет эти шаги) важно и подразумевается буквально. Последовательность фактическая , используемая обработчиком, может соответствовать или не соответствовать этому логическому описанию. Гарантируется, что результаты запроса будут отображаться , как если бы процессор выполнял эти шаги в указанном порядке ...

3 голосов
/ 09 июня 2010

Если это имеет значение, то если у вас ВНЕШНИЕ СОЕДИНЕНИЯ, то вы получите разные результаты от запросов.

См. http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN для объяснения причин.

3 голосов
/ 09 июня 2010

Вывод такой же, так как это inner join, и план запроса должен быть таким же. Я предпочитаю синтаксис в # 1, так как он отделяет объединяющее предложение от предложения фильтра и, таким образом, является более читабельным для меня. Это упрощает повторную проверку предложений ON при чтении большого запроса, поскольку снижает уровень шума, если бы предложения фильтра были смешаны.

Когда вы делаете outer joins, это больше не является вопросом предпочтения - если вы поставите BAR.WEIGHT < 500, это будет иметь прямое влияние на вывод.

0 голосов
/ 10 июня 2010

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

Условия в предложении ON применяются только к объединенной операции.

Итак, определите условия для окончательного набора результатов и операций объединения, а затем добавьте их в нужном месте.

В случае INNER JOIN нет никакой разницы, потому что все операции внутреннего соединения отвечают за окончательный набор результатов (не верно для операции внешнего соединения). Так что это серьезная проблема для outer join случаев.

Добавление условий в нужном месте имеет следующие дополнительные преимущества:

  1. обслуживаемой
    • Легко изменить с inner join на outer join. Не беспокойтесь об условиях.
    • Легко удалить таблицу соединения из запроса.
    • Легко изменить конкретные условия применения. Т.е. условия соединения одинаковы для всех сценариев. Но специфичные для приложения условия (внутри условий WHERE) могут различаться в зависимости от сценария.
  2. Удобочитаемость: проще определить взаимосвязи между таблицами.
0 голосов
/ 10 июня 2010

Является ли 2 плохой синтаксис?Зачем мне это использовать?

Нет ничего плохого в том, чтобы синтаксически поместить предикат в предложение JOIN или в предложение WHERE, так или иначе работает в Oracle.Oracle на самом деле все равно:)

Логически я иногда буду использовать предложения JOIN и WHERE, чтобы большие сложные запросы стали более самодокументируемыми.Например:

SELECT dept.name, SUM(emp.salary)
FROM   dept
JOIN   emp
       ON dept.deptno = emp.deptno
          AND emp.commission IS NULL
WHERE  dept.region = :region
GROUP BY dept.name;

Этот запрос имеет три предиката, один из которых является критерием соединения.Я поместил предикат emp.commission в предложении JOIN, чтобы указать другим разработчикам, что это «не подлежит обсуждению» - в контексте этого запроса этот предикат всегда должен присутствовать.Предикат dept.region находится в предложении WHERE, чтобы указать, что это критерий, предоставленный пользователем.

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

0 голосов
/ 10 июня 2010

Наблюдая за запросами, определенно кажется, что ваши утверждения 1) и 2) могут быть правильными;однако у оптимизатора может быть другое мнение.Я предлагаю вам выполнить эти запросы через EXPLAIN PLAN и посмотреть, действительно ли сгенерированные планы отличаются.

Мне любопытно - какие синтаксические неясности вызывают у вас опасения?Я предпочитаю синтаксис ANSI, потому что для меня гораздо понятнее, что происходит.

Делитесь и наслаждайтесь.

...