Понимание порядка включения ON в самостоятельных соединениях (SQL) - PullRequest
1 голос
/ 20 января 2020

Я пытаюсь понять самосоединение SQL - особенно то, как порядок предложения ON имеет значение в запросе. Это, вероятно, базовый c вопрос, но, пожалуйста, потерпите меня, поскольку я новичок в языке запросов.

На самом деле это LeetCode Question - # 181 , где я пытаюсь чтобы получить сотрудника, чья зарплата выше, чем у их менеджера. Вы можете проверить схему через ссылку LeetCode или пример SQL Fiddle, который я привел ниже.

Вопрос:

В основном я пытаюсь понять разницу в выводе при выполнении следующих двух запросов:

Я изменил порядок ON предложение С (ON e.ManagerId = m.Id) до (ON m.ManagerId = e.Id) и я получаю обратный ответ от желаемого выхода. Я думал, потому что это самообъединение, порядок не имеет значения, так как я извлекаю информацию из идентичной таблицы.

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

1) Правильный запрос для получения желаемого результата

Select *
FROM Employee e
INNER JOIN Employee m
ON e.ManagerId = m.Id
WHERE e.Salary > m.Salary

SQL Пример скрипты

2) Неверный запрос

Select *
FROM Employee e
INNER JOIN Employee m
ON m.ManagerId = e.Id
WHERE e.Salary > m.Salary

SQL Пример Fiddle

Ответы [ 4 ]

3 голосов
/ 20 января 2020

В обоих запросах вы объединяете одного сотрудника с другим. Однако в первом запросе вы вызываете подчиненного e и менеджера m, а во втором - менеджера e и подчиненного m. Давайте посмотрим на это более внимательно:

Select *
FROM Employee e
INNER JOIN Employee m
ON e.ManagerId = m.Id
WHERE e.Salary > m.Salary

Вы объединяете сотрудника (которого вы называете e для краткости) с его менеджером (сотрудник с именем m здесь, идентификатор которого упоминается как идентификатор менеджера в запись сотрудника). Тогда вы сохраняете пары сотрудника и менеджера только там, где зарплата сотрудника больше, чем у менеджера.

Select *
FROM Employee e
INNER JOIN Employee m
ON m.ManagerId = e.Id
WHERE e.Salary > m.Salary

Вы объединяете сотрудника (которого вы называете e для краткости) с его подчиненным (сотрудник по имени m здесь, идентификатор менеджера которого ссылается на запись сотрудника). Таким образом, сотрудник, которого вы называете e, является менеджером другого сотрудника. Тогда вы сохраняете пары сотрудника (менеджера) / подчиненного только там, где зарплата менеджера больше зарплаты подчиненного.

2 голосов
/ 20 января 2020

Функционально порядок не имеет значения (поэтому «ON e.ManagerId = m.Id» совпадает с «ON m.Id = e.ManagerId»).

Что вы делаете здесь объединяются разные столбцы, которые представляют разные вещи.

В неправильном запросе вы говорите, что "managerID managerID совпадает с идентификатором сотрудников", что не соответствует действительности. Менеджеры (как у вас есть в вашей таблице) сами менеджеры не имеют.

То, что вы по существу сделали, это обратное объединение. Если вы поменяете свой знак в вашем where заявлении, поэтому с WHERE e.Salary > m.Salary до WHERE e.Salary < m.Salary вы получите тот же ответ, что и ваш правильный запрос

1 голос
/ 20 января 2020

Вы можете подумать, что только идентификаторы в столбцах Manager_id являются менеджерами.

Таким образом, чтобы получить их имена, вы можете сделать:

select name from Employee where id in (select distinct ManagerId from Employee)

  • отчетливый не является обязательным. Я бы предпочел сделать это, если бы я отменил вложенный выбор, поскольку было бы целесообразно увидеть там один и тот же ManagerId один раз. Два + сотрудника могут потенциально иметь одного и того же менеджера.

Попробуйте выполнить запросы без предложения where, вы увидите те же результаты, но порядок столбцов изменился. Это связано с предложением ON:

  • ON e.ManagerId = m.Id

    (от сотрудника к менеджеру m)

    Или от руки присоедините Employee ManagerId к менеджеру Идентификатор

    Джо в качестве Сотрудника, с Сэм в качестве Менеджера ( восходящая иерархия при чтении по столбцам)

  • ON m.ManagerId = e.Id

    (от менеджера м до сотрудника е)

    Или присоедините Manager ManagerId от руки к идентификатору сотрудника

    Сэм в качестве менеджера, с Джо в качестве Сотрудника ( нисходящая иерархия при чтении по столбцам)

Порядок столбцов не выдерживает, если вы чтобы перевернуть предложение WHERE с > на <=, когда вы изменили порядок префикса ON, вы получите те же результаты.

1 голос
/ 20 января 2020

Я думаю, вы не понимаете, что в таблице упоминаются люди. Копия таблицы m является менеджером, поэтому переменная m.managerId будет ссылаться на менеджера менеджера. Что не то, что вы хотите. Таким образом, правильная ссылка:

e.ManagerId = m.Id

связывает менеджера строки сотрудника с идентификатором строки менеджера.

...