了解SQL JOINS中的ON条件

时间:2018-10-20 01:52:13

标签: sql

以下是我的SQL教科书中的一个问题:

  

人力资源部门想要确定所有员工的姓名   在戴维斯之后被雇用。创建查询以显示姓名和聘用   雇员Davies之后被雇用的任何雇员的日期。

教科书中给出的解决方案是:

SELECT e.last_name, e.hire_date 
FROM employees e 
JOIN employees davies ON (davies.last_name = 'Davies') 
WHERE davies.hire_date < e.hire_date;

我不了解开启状态(davies.last_name = 'Davies')。有人可以向我解释它的作用以及如何帮助解决问题。

3 个答案:

答案 0 :(得分:2)

我发现具有不变条件的join很难遵循。我将使用标量子查询编写此逻辑:

SELECT e.last_name, e.hire_date 
FROM employees e 
WHERE e.hire_date > (SELECT davies.hire_date FROM employees davies WHERE davies.last_name = 'Davies');

我认为这是问题的更直接翻译。您可以随时看到它在做什么。子查询获取Davies的聘用日期。外部查询正在对它们进行比较。

这与JOIN版本略有不同。如果数据具有两个“戴维斯”,则此版本将产生错误。 JOIN版本将生成一组奇怪的重复行,其中可能包含Davies之一。我发现该错误更多是出于示例的精神。

如果要使用JOIN,我将以CROSS JOIN开始:

SELECT e.last_name, e.hire_date 
FROM employees e CROSS JOIN
     employees davies 
WHERE davies.last_name = 'Davies' AND
      davies.hire_date < e.hire_date;

这看起来更“自然”。通常,对单个表的过滤条件在WHERE子句中(尽管一旦您了解了外部联接,这种情况就会改变)。我无法想到将过滤条件放在ON的一个表上然后在WHERE 表之间进行比较的情况。可以,但是对我来说很尴尬。

如果我将其作为一个单独的JOIN展示,我会在ON子句中同时放入 个条件:

SELECT e.last_name, e.hire_date 
FROM employees e JOIN
     employees davies 
     ON davies.last_name = 'Davies' AND
        davies.hire_date < e.hire_date;

答案 1 :(得分:1)

这种类型的联接称为自我联接,其中表与其自身联接。在上面的示例中,ON条件用于过滤别名为davies的employees表。过滤后,davies表将包含employees.last_nameDavies的所有行。一旦有了所有这些行,where条件就是将hire_date表的davies与原始表中的所有员工进行比较,并得到last_namehire_dateDavies之后被雇用。

答案 2 :(得分:0)

在条件davies中是雇员表的别名(第二个表-加入后) 所以它的意思是: 检查联接表(davies表,字段姓氏)中的last_name是否等于单词“ Davies”