以下是我的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'
)。有人可以向我解释它的作用以及如何帮助解决问题。
答案 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_name
为Davies
的所有行。一旦有了所有这些行,where条件就是将hire_date
表的davies
与原始表中的所有员工进行比较,并得到last_name
和hire_date
在Davies
之后被雇用。
答案 2 :(得分:0)
在条件davies中是雇员表的别名(第二个表-加入后) 所以它的意思是: 检查联接表(davies表,字段姓氏)中的last_name是否等于单词“ Davies”