MySQL函数IFNULL不与GROUP BY一起使用

时间:2016-07-12 12:15:51

标签: mysql sql

我有一个包含用户列表的标准表,并且我有一个带有UNIX时间戳的列lastactivity(显示他们何时登录)和列timestamp使用UNIX时间戳显示他们何时注册。

我构建了一个SQL查询,显示从现在起24小时(86400秒)内有多少用户处于活动状态,并按星期对结果进行分组,以便计数器计算每周注册的用户数量:

SELECT
    IFNULL(COUNT(*),0) as `counter`,
    (WEEK(`timestamp`)) as `week`
FROM
    `clients`
WHERE
    (CAST(UNIX_TIMESTAMP() as signed) - CAST(`lastactivity` as signed)) <= 86400
GROUP BY
    WEEK(`timestamp`);

问题是函数IFNULL(COUNT(*),0)无法正常工作。如果计数器上存在NULL / 0,即使使用IFNULL() MySQL函数,此SQL查询也不会显示星期。这可能是因为GROUP BY的工作原理。例如,我会得到这样的结果:

counter | week
   2    |  11
   1    |  13
   9    |  14
   6    |  17

但我想每周都这样展示:

counter | week
   2    |  11
   0    |  12
   1    |  13
   9    |  14
   0    |  15
   0    |  16
   6    |  17

任何人都知道我该如何解决这个问题?

戈登试图通过LEFT JOIN查询来帮助我,但我仍然得到相同的结果,也许我在这里做错了什么:

SELECT
    COUNT(a.id) as `counter`,
    (WEEK(b.timestamp)) as `week`
FROM
    `users` a
LEFT JOIN
    `users` b
ON
    a.id = b.id
WHERE
    (CAST(UNIX_TIMESTAMP() as signed) - CAST(a.lastactivity as signed)) <= 86400
GROUP BY
    WEEK(b.timestamp);

1 个答案:

答案 0 :(得分:1)

评论太长了。

问题是您不了解查询的工作原理。 IFNULL()(或标准版本COALESCE()值NULL转换为其他值。但是,COUNT()永远不会返回NULL。所以把它留下来:

SELECT COUNT(*) as `counter`, WEEK(`timestamp`) as `week`
FROM `clients`
WHERE (CAST(UNIX_TIMESTAMP() as signed) - CAST(`lastactivity` as signed)) <= 86400
GROUP BY WEEK(`timestamp`);

您的问题是缺少行,而不是NULL值。您必须使用LEFT JOIN解决此问题。

编辑:

您需要left join来包含所有周:

SELECT COUNT(c.timestamp) as `counter`, wk as `week`
FROM (SELECT 11 as wk UNION ALL
      SELECT 12 UNION ALL
      SELECT 13 UNION ALL
      SELECT 14 UNION ALL
      SELECT 15 UNION ALL
      SELECT 16 UNION ALL
      SELECT 17
     ) w LEFT JOIN
     `clients` c
     ON WEEK(c.`timestamp`) = w.wk
WHERE (CAST(UNIX_TIMESTAMP() as signed) - CAST(`lastactivity` as signed)) <= 86400
GROUP BY WEEK(`timestamp`);