MySQL 8.0返回0行,并插入LEFT JOIN以返回1行,列值为0

时间:2018-12-16 16:30:24

标签: mysql sql

这是SQL查询:

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end on call_out_end.employer_id = user.id
where user.id = 949 and call_out_end.callstart >= '2018-12-09 00:00:00'
group by user.id

此查询恰好返回0行(应返回1行,列调用= 0)。

enter image description here

如果我确实将SQL查询更改为:

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end on call_out_end.employer_id = user.id
where user.id = 949
group by user.id

MySQLWorkbench返回1行:

enter image description here

...但这不是我想要的:)

我要提到的是,没有没有记录满足以下条件:call_out_end.callstart >= '....',因此我希望收到0个呼叫。

我在哪里做错了什么?

2 个答案:

答案 0 :(得分:1)

left join中第二个表上的过滤器需要进入on子句:

select u.*, count(coe.id) as calls
from user u left join
     call_out_end coe
     on coe.employer_id = user.id and
        coe.callstart >= '2018-12-09'
where u.id = 949 
group by u.id;

当条件位于WHERE子句中时,外部联接将变为内部联接。为什么? callstart的不匹配值具有NULL的值,比较失败。

请注意,我还向查询中添加了表别名。这使得书写和阅读更加容易。我还从日期常量中删除了时间部分。没必要。

假设group by u.idu.id中的主键(毫无疑问),users没问题。

答案 1 :(得分:1)

您正在使用LEFT JOIN来可选地匹配表辅助表call_out_end。如果没有匹配项,您仍然希望显示主表user中的记录。

查询的问题是您的WHERE子句引用了辅助表(callstart)中的一个字段。因此,当LEFT JOIN不匹配时,callstart子句中的NULL出现在WHERE中,导致相应的记录被过滤掉。

要解决此问题,您需要将该字段上的过滤器从WHERE子句移到ON的{​​{1}}部分。

LEFT JOIN

从概念上讲,这与丑陋的查询相同:

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end
    on call_out_end.employer_id = user.id
    and call_out_end.callstart >= '2018-12-09 00:00:00'
where user.id = 949
group by user.id