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

时间:2017-07-07 13:24:36

标签: sql ms-access outer-join

我有这两个表:

算:

Id Nome
--+----
 1 JDOE
 2 RROE
 3 MMOE

呼叫:

Id CallDate OpId
--+--------+----
 1 20161228    2
 2 20161228    3
 3 20161228    2
 4 20161228    3
 5 20170104    1
 6 20170104    2
 7 20170104    1    

这个查询:

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;

返回:

Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1

我怎样才能让它返回呢?

Id Nome CountCalls
--+----+----------
 1 JDOE          2
 2 RROE          1
 3 MMOE          0

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

PS。这是ACCESS 2013

PS2。我已经阅读了this answer,但无法看到它与我所做的有什么不同,所以如果有人可以帮我(也许有其他人有同样的疑问)重复我会非常感激。

非常感谢!

2 个答案:

答案 0 :(得分:5)

由于您在Calls.CallDate子句中引用了HAVING,因此您将删除没有呼叫的运营商。如果没有通话,则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;

您也不需要按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;

旁边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;

如果您希望在HAVING上进行游戏,则可以使用CountCalls,例如,如果您只想要进行多次拨打电话的运营商可以使用:

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;

这只会返回

Id Nome CountCalls
--+----+----------
 1 JDOE          2

答案 1 :(得分:2)

尝试以下查询:

SELECT o.id, o.name, count(c.opid) as countcalls
FROM Operators o LEFT JOIN calls c ON o.id = c.opid AND c.calldate=20170104
GROUP BY c.calldate, o.id, o.name
ORDER BY o.id;

<强>输出:

+------+------+------------+
| id   | name | countcalls |
+------+------+------------+
|    1 | JDOE |          2 |
|    2 | RROE |          1 |
|    3 | MMOE |          0 |
+------+------+------------+