如何在查询中包含零计数结果

VBo*_*Cat 3 sql ms-access outer-join

我有这两个表:

运营商:

Id Nome
--+----
 1 JDOE
 2 RROE
 3 MMOE
Run Code Online (Sandbox Code Playgroud)

呼叫:

Id CallDate OpId
--+--------+----
 1 20161228    2
 2 20161228    3
 3 20161228    2
 4 20161228    3
 5 20170104    1
 6 20170104    2
 7 20170104    1    
Run Code Online (Sandbox Code Playgroud)

而这个查询:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
GROUP BY Calls.CallDate, Operators.id, Operators.Nome
HAVING Calls.CallDate=20170104;
Run Code Online (Sandbox Code Playgroud)

哪个回报:

Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1
Run Code Online (Sandbox Code Playgroud)

我怎样才能让它归还呢?

Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1
 3 MMOE          0
Run Code Online (Sandbox Code Playgroud)

也就是说,如何在任何查询中包含主表的零结果,该结果在左连接表中没有出现,至少在查询过滤标准定义的数据切片中?

PS.这是ACCESS 2013

PS2.我已经阅读了这个答案,但是看不出它与我正在做的有什么不同,所以如果有人能帮助我(也许是其他有同样疑问的人),那么在我复制之前我会非常感激.

非常感谢你!

Gar*_*thD 7

因为您Calls.CallDateHAVING子句中有引用,所以您将删除没有调用的运算符.如果没有调用,那么CallDate将是NULL,而NULL=20170104不是真的,所以这些行被排除在外.您需要将此谓词移动到join子句:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON (Operators.id = Calls.OpId AND Calls.CallDate=20170104)
GROUP BY Calls.CallDate, Operators.id, Operators.Nome;
Run Code Online (Sandbox Code Playgroud)

你也不需要分组Calls.CallDate,因为你只有一个,所以你可以使用:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON (Operators.id = Calls.OpId AND Calls.CallDate=20170104)
GROUP BY Operators.id, Operators.Nome;
Run Code Online (Sandbox Code Playgroud)

抛开HAVING是错误的操作员.HAVING用于过滤聚合,因为您没有过滤聚合,您应该使用WHERE

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
WHERE Calls.CallDate=20170104
GROUP BY Calls.CallDate, Operators.id, Operators.Nome;
Run Code Online (Sandbox Code Playgroud)

您可以使用,HAVING如果您想要进行过滤CountCalls,例如,如果您只想要进行超过1次呼叫的运营商,您可以使用:

SELECT Operators.id, Operators.Nome, Count(Calls.OpId) AS CountCalls
FROM Operators LEFT JOIN Calls ON Operators.id = Calls.OpId
WHERE Calls.CallDate=20170104
GROUP BY Calls.CallDate, Operators.id, Operators.Nome
HAVING Count(Calls.OpId) > 1;
Run Code Online (Sandbox Code Playgroud)

这只会回来

Id Nome CountCalls
--+----+----------
 1 JDOE          2
Run Code Online (Sandbox Code Playgroud)