这是一个包含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顺序)
答案 0 :(得分:1)
通常,更改连接顺序不会有什么不同-如果查询编译,则它应该返回相同的结果。
但是,您正在使用using
子句。这可能会引起问题,因为联接键的作用域仅限于当时的表。
一种可能性是至少三个表具有department_id
表:employees
,departments
和jobs
表中的一个或两个。
第一个查询是在department_id
中查找作业表,并要求它们相同。
第二个查询也将employees.department_id
引入了范围,并要求它与其他查询匹配。没有行的员工的部门与分配给他们的工作部门相匹配。
答案 1 :(得分:0)
之前:使用“使用”通常不是一个好主意,因为它结合了所有通知的缺点,很少使用且难以维护。
使用,如另一个答案所述,将上表中的所有(且仅)列合并。我将通过示例解释如何使用此方法。首先返回的行是
Administration Assistant Executive Jennifer Whalen 1995-09-17
如果我们专注于此行,让我们看看第一个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 |
现在,我们进行第二个Join。到目前为止,唯一包含Department_id的表是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相同:
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:
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)
在两个不同的表中分别包含department_id列,即job_history(90)和employee(10)。因此,没有任何匹配项。
-> 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'
;