我们正在尝试计算每天拨打特定号码的唯一电话号码的数量,其中0(或NULL)表示没有呼叫的天数。为了简化数据模式,我们的表包含四个字段:
| id | fromz | toz | date |
fromz: inbound call number
toz: number called
date: yyyy-mm-dd
当我们需要知道的是每天调用多少个唯一号码 - 并且不关心所谓的号码时 - 在结果中包含无通话天数很简单。
我们加入另一个仅包含连续日期的表:日历
| id | date |
date:yyyy-mm-dd
SELECT p.fromz, count(unique(p.fromz)), p.date FROM phones p
RIGHT OUTER JOIN calendar c ON
p.date = c.date
GROUP BY c.date
如果c.date上没有p.fromz,那个p.date的结果是“0”(或NULL)
当我们开始按名称排序时出现问题:
SELECT p.fromz, count(unique(p.fromz)), p.date FROM phones p
RIGHT OUTER JOIN calendar ON
p.date = c.date
WHERE p.toz = "@myNumber"
GROUP BY c.date
因为在某些日子里没有WHERE toz = @myNumber我们只在(WHERE)有@myNumber调用的日子得到结果。
有什么建议吗?
答案 0 :(得分:0)
我稍微修改了一些字段名称。我不确定这100%是否符合您的使用案例,但如果没有,您应该能够从这里弄明白。基本上,将当前的WHERE
条件移动到ON
子句中。
SELECT p.fromz, count(distinct p.fromz), p.callDate, c.theDate FROM phones p
RIGHT OUTER JOIN calendar c ON
p.callDate = c.theDate AND p.toz = 2125555555
GROUP BY c.theDate
完全披露
这不符合标准。对于合规查询,请查看Ollie的答案,只需将p.toz
部分从WHERE
移至ON
即可获得所需的结果。
答案 1 :(得分:0)
你非常接近。
你正在使用令人讨厌的MySQL非标准扩展程序GROUP BY
,它会让你发疯,因为它让你的许多人在你面前疯狂。
http://dev.mysql.com/doc/refman/5.5/en/group-by-extensions.html
您需要遵循标准GROUP BY
的规则。这些规则指定SELECT子句中提到的每一列必须是(1)在GROUP BY
子句中也提到或(2)聚合函数。
您的查询中存在两个问题。一个是您在p.date
子句中提到c.date
而不是SELECT
。如果您p.date
表中的相关日期没有任何项目,phones
将为空。第二项是你提到p.fromz两次。
我认为您的基本汇总查询应该如下http://sqlfiddle.com/#!2/0ef4e/3/0:
SELECT p.toz,
COUNT(DISTINCT p.fromz) AS unique_calling_number_count,
c.date
FROM phones AS p
RIGHT OUTER JOIN calendar AS c ON p.date = c.date
GROUP BY p.toz, c.date
ORDER BY c.date, p.toz
这将按天和呼叫目的地号码汇总呼叫始发号码。
然后,当您需要根据某种标准过滤phones
条记录时,请在子查询中执行以下操作。
SELECT p.toz,
COUNT(DISTINCT p.fromz) AS unique_calling_number_count,
c.date
FROM (
SELECT * /* filtering subquery */
FROM phones
WHERE toz = "@myNumber"
) AS p
RIGHT OUTER JOIN calendar AS c ON p.date = c.date
WHERE p.toz = "@myNumber"
GROUP BY p.toz, c.date
ORDER BY c.date, p.toz
以下是此工作的一个示例。 http://sqlfiddle.com/#!2/0ef4e/2/0感谢@PatrickQ在错误的查询级别注意到WHERE。