это подзапрос или просто внутреннее соединение - PullRequest
0 голосов
/ 02 июля 2018

Я изучаю концепцию подзапроса, ниже приведен один запрос, извлеченный из википедии https://en.wikipedia.org/wiki/Correlated_subquery

SELECT employees.employee_number, employees.name
   FROM employees INNER JOIN
     (SELECT department, AVG(salary) AS department_average
       FROM employees
       GROUP BY department) AS temp ON employees.department = temp.department
   WHERE employees.salary > temp.department_average;

sql - это переписанная версия коррелированного подзапроса, как показано ниже

 SELECT
   employee_number,
   name,
   (SELECT AVG(salary) 
      FROM employees
      WHERE department = emp.department) AS department_average
   FROM employees AS emp;

А теперь мой вопрос: Является ли sql из переписанной версии подзапросом? Я так запутался в этом

  INNER JOIN
         (SELECT department, AVG(salary) AS department_average
           FROM employees
           GROUP BY department) AS temp ON employees.department = temp.department
       WHERE employees.salary > temp.department_average;

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Не совсем. Эквивалентом будет left join. Коррелированная версия сохраняет все строки в таблице employees, даже если нет совпадений. inner join требует совпадения.

Как правило, планы выполнения не будут одинаковыми, потому что механизм SQL не знает заранее, совпадают ли все строки.

С дополнительным условием фильтрации две версии эквивалентны. Обратите внимание, что для фильтра для коррелированной версии требуется подзапрос или CTE, поскольку предложение where не распознает псевдонимы столбцов.

0 голосов
/ 02 июля 2018

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

Я бы сказал, если это в предложении FROM, это называется объединением:

SELECT employee_id, department_name
  FROM employees JOIN departments USING (department_id);

Если это в предложении WHERE, он называется подзапросом:

SELECT employee_id
  FROM employees
 WHERE employee_id = (
         SELECT manager_id
           FROM departments
          WHERE employees.employee_id = departments.manager_id);

Если он входит в предложение SELECT, он называется скалярным подзапросом (спасибо, @Matthew McPeak):

SELECT employee_id,
       (SELECT department_name
          FROM departments
         WHERE departments.department_id = employees.department_id)
  FROM employees;
...