这是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)。
如果我确实将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行:
...但这不是我想要的:)
我要提到的是,没有没有记录满足以下条件:call_out_end.callstart >= '....'
,因此我希望收到0个呼叫。
我在哪里做错了什么?
答案 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.id
是u.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