Reputation: 1
Here's an exercise with 4 tables: https://www.w3resource.com/sql-exercises/joins-hr/sql-joins-hr-exercise-13.php
I am trying to understand why using:
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';
returns a correct value, while using
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';
returns nothing (just changed JOIN order)
Upvotes: 0
Views: 56
Reputation: 31
Before: Using 'USING' is often a bad idea, because it combines disadvantages from all notaitions, is seldom used and difficult to maintain.
USING, as stated in an other answer, joins all (and only) columns in the tables above. I'll explain by example how this using works. The Row returned in the first place is
Administration Assistant Executive Jennifer Whalen 1995-09-17
If we concentrate on this Row, let us see the origin of the first Join:
JOIN jobs USING (job_id)
job_history
| 200 | 1995-09-17 | 2001-06-17 | AD_ASST | 90 |
jobs
| AD_ASST | Administration Assistant | 3000 | 6000 |
Now we proceed to the second Join. The only table until now containing the department_id is job_history.
JOIN departments USING (department_id)
| 90 | Executive | 100 | 1700 |
and the last join:
JOIN employees USING (employee_id)
| 200 | Jennifer | Whalen | JWHALEN | 515.123.4444 | 2003-09-17 | AD_ASST | 4400.00 | 0.00 | 101 | 10 |
because the only other table above having a row named employee_id is job_history.
Let us see what happens, if you switch the joins. The first Join is just the same:
JOIN jobs USING (job_id)
job_history
| 200 | 1995-09-17 | 2001-06-17 | AD_ASST | 90 |
jobs
| AD_ASST | Administration Assistant | 3000 | 6000 |
Now we proceed to the second Join:
JOIN employees USING (employee_id)
| 200 | Jennifer | Whalen | JWHALEN | 515.123.4444 | 2003-09-17 | AD_ASST | 4400.00 | 0.00 | 101 | 10 |
But now we come to the important Difference:
JOIN departments USING (department_id)
There are department_id columns in two different tables, job_history (90) and employees (10). So there cannot be any match.
-> NO DATA FOUND:
So: Use JOIN with 'ON' instead of 'USING' and fully qualify any column with the appropriate table aliase so you won't get into this kind of trouble and have maintainable code. Here we go:
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'
;
Upvotes: 0
Reputation: 1269633
In general, changing the order of the joins should not make a difference -- if the query compiles, then it should return the same results.
However, you are using the using
clause. And that can cause problems, because the scoping of the join keys is only tables up to that point.
One possibility is that at least three tables have a department_id
: employees
, departments
and one or both of the jobs
tables.
The first query is looking up the department_id
for the jobs tables, and requiring that they be the same.
The second query brings the employees.department_id
in scope as well, and requires that it match the others. No rows have employees whose department matches the department of jobs they are assigned to.
Upvotes: 1