如何在查询中包含零计数结果
How to include zero-count results in query
我有这两个 table:
运营商:
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;
哪个 returns:
Id Nome CountCalls
--+----+----------
1 JDOE 2
2 RROE 1
我怎样才能做到 return 这个呢?
Id Nome CountCalls
--+----+----------
1 JDOE 2
2 RROE 1
3 MMOE 0
也就是说,如何在任何查询中也包括 main table 的零结果,它在左连接 table 中没有出现,至少在查询过滤条件定义的数据片中?
这是 Access 2013。
我读过 this answer 但看不出它与我正在做的有何不同。
因为您在 HAVING
子句中引用了 Calls.CallDate
,所以您要删除没有调用的运算符。如果没有调用,则 CallDate
将是 NULL
,而 NULL=20170104
不正确,因此排除这些行。您需要将此谓词移动到您的连接子句中:
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;
如果你想在 CountCalls
上筛选,你可以使用 HAVING
,例如,如果你只想要调用超过 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;
这只会return
Id Nome CountCalls
--+----+----------
1 JDOE 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 |
+------+------+------------+
我有这两个 table:
运营商:
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;
哪个 returns:
Id Nome CountCalls
--+----+----------
1 JDOE 2
2 RROE 1
我怎样才能做到 return 这个呢?
Id Nome CountCalls
--+----+----------
1 JDOE 2
2 RROE 1
3 MMOE 0
也就是说,如何在任何查询中也包括 main table 的零结果,它在左连接 table 中没有出现,至少在查询过滤条件定义的数据片中?
这是 Access 2013。
我读过 this answer 但看不出它与我正在做的有何不同。
因为您在 HAVING
子句中引用了 Calls.CallDate
,所以您要删除没有调用的运算符。如果没有调用,则 CallDate
将是 NULL
,而 NULL=20170104
不正确,因此排除这些行。您需要将此谓词移动到您的连接子句中:
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;
如果你想在 CountCalls
上筛选,你可以使用 HAVING
,例如,如果你只想要调用超过 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;
这只会return
Id Nome CountCalls
--+----+----------
1 JDOE 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 |
+------+------+------------+