我有一个包含用户列表的标准表,并且我有一个带有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);
答案 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`);