Как влияет порядок соединения с пользователем? - PullRequest
0 голосов
/ 23 мая 2019

Вот упражнение с 4 столами: https://www.w3resource.com/sql-exercises/joins-hr/sql-joins-hr-exercise-13.php

Я пытаюсь понять, почему использую:

 SELECT job_title, department_name, first_name || ' ' || last_name AS `enter code here`Employee_name, start_date 
    FROM job_history 
    JOIN jobs USING (job_id) 
    JOIN departments USING (department_id) 
    JOIN  employees USING (employee_id)
WHERE start_date>='1993-01-01' AND start_date<='1997-08-31';

возвращает правильное значение при использовании

 SELECT job_title, department_name, first_name || ' ' || last_name AS Employee_name, start_date 
    FROM job_history 
    JOIN jobs USING (job_id) 
    JOIN  employees USING (employee_id) 
    JOIN departments USING (department_id) 
WHERE start_date>='1993-01-01' AND start_date<='1997-08-31';

ничего не возвращает (только что измененный порядок JOIN)

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Как правило, изменение порядка объединений не должно иметь значения - если запрос компилируется, то он должен возвращать те же результаты.

Однако вы используете предложение using.И это может вызвать проблемы, потому что область действия ключей объединения - только таблицы до этой точки .

Одна возможность состоит в том, что по крайней мере три таблицы имеют department_id: employees, departments и одна или обе таблицы jobs.

Первый запрос ищет department_id для таблиц заданий и требует, чтобы они были одинаковыми.

Второй запрос также вводит область действия employees.department_id и требует, чтобы он соответствовал другим.Ни в одной строке нет сотрудников, чей отдел совпадает с заданием, которому они назначены.

0 голосов
/ 24 мая 2019

Раньше: использование «ИСПОЛЬЗОВАНИЯ» часто является плохой идеей, потому что оно сочетает в себе недостатки всех нотаций, редко используется и трудно поддерживается.

ИСПОЛЬЗОВАНИЕ, как указано в другом ответе, объединяет все (и только) столбцы в таблицах выше. Я объясню на примере, как это работает. Строка, возвращенная на первое место, составляет

Administration Assistant    Executive   Jennifer Whalen 1995-09-17

Если мы сконцентрируемся на этой строке, давайте посмотрим на происхождение первого соединения:

JOIN jobs USING (job_id) 

job_history
|         200 | 1995-09-17 | 2001-06-17 | AD_ASST    |            90 |

jobs
| AD_ASST    | Administration Assistant        |       3000 |       6000 |

Теперь перейдем ко второму соединению. До сих пор единственная таблица, содержащая идентификатор отдела, - это job_history.

JOIN departments USING (department_id) 

|            90 | Executive            |        100 |        1700 |

и последнее присоединение:

JOIN  employees USING (employee_id)

|         200 | Jennifer    | Whalen      | JWHALEN  | 515.123.4444       | 2003-09-17 | AD_ASST    |  4400.00 |           0.00 |        101 |            10 |

потому что единственная таблица выше, имеющая строку с именем employee_id, - это job_history.

Давайте посмотрим, что произойдет, если вы переключите соединения. Первое соединение точно такое же:

JOIN jobs USING (job_id) 

job_history
|         200 | 1995-09-17 | 2001-06-17 | AD_ASST    |            90 |

jobs
| AD_ASST    | Administration Assistant        |       3000 |       6000 |

Теперь перейдем ко второму. Присоединиться:

JOIN  employees USING (employee_id)

|         200 | Jennifer    | Whalen      | JWHALEN  | 515.123.4444       | 2003-09-17 | AD_ASST    |  4400.00 |           0.00 |        101 |            10 |

Но теперь мы подошли к важной разнице:

JOIN departments USING (department_id) 

В двух разных таблицах: job_history (90) и employee (10), есть столбцы Department_id. Так что не может быть никакого совпадения.

-> NO DATA FOUND:

Итак: используйте JOIN с 'ON' вместо 'USING' и полностью определите любой столбец с соответствующим псевдонимом таблицы, чтобы вы не столкнулись с подобными проблемами и имели поддерживаемый код. Вот и мы:

SELECT job_title
      ,department_name
      ,first_name || ' ' || last_name AS Employee_name
      ,start_date
FROM job_history joh
JOIN jobs        jos on (joh.job_id = jos.job_id) 
JOIN departments dep on (joh.department_id = dep.department_id) 
JOIN employees   emp on (joh.employee_id = emp.employee_id)
WHERE start_date>='1993-01-01' AND start_date<='1997-08-31'
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...