Левое соединение или выбор из нескольких таблиц с помощью запятой (,)

Мне любопытно, почему нам нужно использовать LEFT JOIN, так как мы можем использовать запятые для выбора нескольких таблиц.

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

Какой из них быстрее?

Вот мой код:

   SELECT mw.*, 
          nvs.* 
     FROM mst_words mw 
LEFT JOIN (SELECT no as nonvs, 
                  owner, 
                  owner_no, 
                  vocab_no, 
                  correct 
             FROM vocab_stats 
            WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0 ) 
      AND mw.level = 1

... и:

SELECT * 
  FROM vocab_stats vs, 
       mst_words mw 
 WHERE mw.no = vs.vocab_no 
   AND vs.correct > 0 
   AND mw.level = 1 
   AND vs.owner = 1111

Ответ 1

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

   SELECT mw.*, 
          nvs.* 
     FROM mst_words mw 
LEFT JOIN (SELECT *
             FROM vocab_stats 
            WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0 ) 
      AND mw.level = 1

Таким образом, mw. * и nvs. * вместе образуют тот же набор, что и второй запрос сингулярный *. Запрос, который вы написали, может использовать INNER JOIN, поскольку он включает фильтр на nvs .correct.

Общий вид

TABLEA LEFT JOIN TABLEB ON <CONDITION>

attempts, чтобы найти записи TableB на основе условия. Если сбой завершается, результаты TABLEA сохраняются, при этом все столбцы из TableB равны NULL. В отличие от

TABLEA INNER JOIN TABLEB ON <CONDITION>

также attempts, чтобы найти записи TableB на основе условия. Однако, при сбое, конкретная запись из таблицы А удаляется из выходного результирующего набора.

Стандарт ANSI для CROSS JOIN создает декартово произведение между двумя таблицами.

TABLEA CROSS JOIN TABLEB
  -- # or in older syntax, simply using commas
TABLEA, TABLEB

Цель синтаксиса состоит в том, что КАЖДАЯ строка в TABLEA соединена с КАЖДОЙ строкой в ​​TABLEB. Таким образом, 4 строки в и 3 строки в B производят 12 строк вывода. При сопряжении с условиями в предложении WHERE он иногда вызывает одно и то же поведение INNER JOIN, поскольку они выражают одно и то же (условие между A и B = > сохранить или нет). Тем не менее, это намного яснее, когда вы читаете о намерении, когда вы используете INNER JOIN вместо запятых.

По производительности, большинство СУБД будут обрабатывать LEFT-соединение быстрее, чем INNER JOIN. Обозначение запятой может привести к тому, что системы баз данных неверно истолковывают намерение и создают плохой план запроса - вот еще один плюс для нотации SQL92.

Зачем нам нужен LEFT JOIN? Если объяснение LEFT JOIN выше все еще недостаточно (вести записи в без совпадений в B), тогда подумайте, что для достижения того же вам понадобится сложный СОЮЗ между двумя наборами, используя старую запятую для достижения такого же эффекта. Но, как указано ранее,, это не относится к вашему примеру, который действительно является INNER JOIN, скрывающимся за LEFT JOIN.

Примечания:

  • ПРАВИЛЬНАЯ РАБОТА совпадает с LEFT, за исключением того, что она начинается с TABLEB (справа) вместо A.
  • RIGHT и LEFT JOINS - оба соединения OUTER. Слово OUTER является необязательным, то есть оно может быть записано как LEFT OUTER JOIN.
  • Третий тип соединения OUTER - это объединение FULL OUTER, но это не обсуждается здесь.

Ответ 2

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

Два примера, которые вы указали, на самом деле не эквивалентны, так как вы включили подзапрос в первом примере. Это лучший пример:

SELECT vs.*, mw.*
FROM vocab_stats vs, mst_words mw
LEFT JOIN vocab_stats vs ON mw.no = vs.vocab_no
WHERE vs.correct > 0 
AND mw.level = 1
AND vs.owner = 1111