【发布时间】:2021-06-05 22:02:52
【问题描述】:
我正在尝试查找过去 30 天内的管理员活动。
accounts 表存储用户数据(用户名、密码等)
每天结束时,如果用户已登录,它将在 player_history 表中创建一个包含更新数据的新条目。这样我们就可以随着时间的推移跟踪进度。
帐户表:
| id | username | admin |
|---|---|---|
| 1 | Michael | 4 |
| 2 | Steve | 3 |
| 3 | Louise | 3 |
| 4 | Joe | 0 |
| 5 | Amy | 1 |
player_history 表:
| id | user_id | created_at | playtime |
|---|---|---|---|
| 0 | 1 | 2021-04-03 | 10 |
| 1 | 2 | 2021-04-04 | 10 |
| 2 | 3 | 2021-04-05 | 15 |
| 3 | 4 | 2021-04-10 | 20 |
| 4 | 5 | 2021-04-11 | 20 |
| 5 | 1 | 2021-05-12 | 40 |
| 6 | 2 | 2021-05-13 | 55 |
| 7 | 3 | 2021-05-17 | 65 |
| 8 | 4 | 2021-05-19 | 75 |
| 9 | 5 | 2021-05-23 | 30 |
| 10 | 1 | 2021-06-01 | 60 |
| 11 | 2 | 2021-06-02 | 65 |
| 12 | 3 | 2021-06-02 | 67 |
| 13 | 4 | 2021-06-03 | 90 |
以下查询
SELECT a.`username`, SEC_TO_TIME((MAX(h.`playtime`) - MIN(h.`playtime`))*60) as 'time' FROM `player_history` h, `accounts` a WHERE h.`created_at` > '2021-05-06' AND h.`user_id` = a.`id` AND a.`admin` > 0 GROUP BY h.`user_id`
输出此表:
请注意,这只是管理员活动,因此 Joe 不包含在此数据中。
从 2021-05-06 至今 (yy-mm-dd):
| username | time |
|---|---|
| Michael | 00:20:00 |
| Steve | 00:10:00 |
| Louise | 00:02:00 |
| Amy | 00:00:00 |
从数据中可以看出,Amy 的时间显示为 0,尽管她在上个月玩了 10 分钟。这是因为她从 2021-05-06 开始只有 1 个条目,因此没有可比较的数据。它是 0,因为 10-10 = 0。
另一个缺陷是它不包括上个月的所有活动,基本上只是从最低值中减去最高值。
因此,我尝试通过将 2021-05-06 之后的最高值与他们在该日期之前的最近一次登录进行比较来解决此问题。所以我稍微修改了一下查询:
SELECT a.`Username`, SEC_TO_TIME((MAX(h.`playtime`) - (SELECT MAX(`playtime`) FROM `player_history` WHERE a.`id` = `user_id` AND `created_at` < '2021-05-06'))*60) as 'Time' FROM `player_history` h, `accounts` a WHERE h.`created_at` >= '2021-05-06' AND h.`user_id` = a.`id` AND a.`admin` > 0 GROUP BY h.`user_id`
所以现在它会输出:
| username | time |
|---|---|
| Michael | 00:50:00 |
| Steve | 00:50:00 |
| Louise | 00:52:00 |
| Amy | 00:10:00 |
但我觉得整个查询效率很低。有没有更好的方法来做到这一点?
【问题讨论】:
-
这段代码存在 很多 缺陷,首先是因为
select和group by不一致,所以它在语法上不正确。我建议您提供示例数据、期望的结果以及对您想要完成的目标的清晰说明。 -
我已经编辑了@GordonLinoff 的原帖
-
我已经编辑了我的原始帖子? @草莓
-
是的。我们可以看到。
标签: mysql sql subquery correlated