JOIN USING的顺序如何产生影响?

时间:2019-05-23 19:30:21

标签: sql join

这是一个包含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 个答案:

答案 0 :(得分:1)

通常,更改连接顺序不会有什么不同-如果查询编译,则它应该返回相同的结果。

但是,您正在使用using子句。这可能会引起问题,因为联接键的作用域仅限于当时的表

一种可能性是至少三个表具有department_id表:employeesdepartmentsjobs表中的一个或两个。

第一个查询是在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'
;