当我在两个表之间以INNER JOIN
运行查询时,我得到了正确的结果 - 总共182个。
但是,当我以LEFT JOIN
运行查询时,我只返回8条记录。我是否错误地执行了连接?
首先是代码:
select e.username,
e.password,
coalesce(r.access_level, 0) as orgid
from employees e
left join retired r
on e.employeeid = r.employeeid
where access_level=3
Retired
表只有182条记录。这两个表都与EmployeeId
相关联。
Retired
表中的82条记录也存在于Employees
中,但Employees
表中有超过7千条记录。
其中一个字段名Retired
名为Access_Level
,值为3.
为什么LEFT JOIN
没有给我一个准确的结果?
答案 0 :(得分:2)
在WHERE子句中使用退役表中的字段基本上是自动执行INNER JOIN,因为只返回具有有效access_level值(即NOT NULL)的记录。
如果要查看员工的所有记录,则需要修改WHERE子句以考虑退休时没有匹配的员工记录,例如说WHERE r.access_level = 3 OR r.employeeid IS NULL
。
答案 1 :(得分:2)
如果Access_Level
是Retired
表中的列,那么对于员工中没有退休相应行的任何行,其值将为NULL
。然后,这些行将被WHERE子句过滤掉,因为它们不的Access_Level
为3.将该条件移动到ON
子句就足够了:
select e.username,
e.password,
coalesce(r.access_level, 0) as orgid
from employees e
left join retired r
on e.employeeid = r.employeeid and access_level=3
答案 2 :(得分:1)
外连接和条件的技巧是将条件从where子句移动到join condtions子句中:
select
e.username,
e.password,
coalesce(r.access_level, 0) as orgid
from employees e
left join retired r
on e.employeeid = r.employeeid
and access_level=3
你必须这样做的原因是where子句是行集上的过滤器,它在连接之后执行。通过在where子句中的外连接表上设置条件,可以有效地将外连接变为内部连接,因为错过的外连接在连接表的列中具有null
值,但是where子句中的条件会坚持 那里的值。
join子句中的条件在连接时执行,因此通过将条件移出where子句,允许连接在仍然强加条件时错过 ,但如果在连接表中找不到合适的行,则返回一个全空连接行。
在评论中获得更多信息后,似乎这就是你想要的:
select distinct
e.username,
e.password,
coalesce(r.access_level, 0) as orgid
from employees e
join retired r
on e.employeeid = r.employeeid
and access_level=3