按周分组,显示空周 - 使用where子句

时间:2014-04-04 18:54:48

标签: mysql join

我们正在尝试计算每天拨打特定号码的唯一电话号码的数量,其中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调用的日子得到结果。

有什么建议吗?

2 个答案:

答案 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

SQLFiddle

完全披露 这不符合标准。对于合规查询,请查看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。