我有两个表,Users
和 Visitors
。在 Users
中,我拥有所有用户信息,在 Visitors
中,我放置了登录结果。每次用户登录时,都会有一条新记录进入 Visitors
,其中包含 user_id
和 datetime
。
我想选择具有上次登录的日期时间 的所有用户。我该怎么做?
最佳答案
为了避免使用子查询来计算每个用户的最近时间(这实际上意味着为 n
用户运行 n
查询),使用 mysql 的“技巧” group by
without 聚合,它返回每个组的第一行:
select u.*, last_login
from users u
left join (select id, last_login
from (select u.id, v.last_login
from users u
join visits v on v.user_id = u.id
order by 1, 2 desc
) x
group by 1) y on y.id = u.id;
这个查询会执行得很好,只对访问表 9 进行一次传递,没有针对每个用户的子查询)。
下面是对正在发生的事情的分解:
- 最内层的查询(别名为
x
)按顺序获取用户 ID 和 last_visit,以及我们希望每个用户 ID 中第一个的 last_visit 值 - 下一个查询(别名为
y
)使用group by
对用户 id 而不使用任何聚合函数。在其他数据库中,这将是一个错误,但是对于 mysql,它返回每个组的 first 行 - 即我们想要的 last_visit 值(刚刚对行进行排序) - 最后的最外层查询对这些结果执行
左连接
,为从未访问过的用户提供null
值,否则提供我们想要加入的last_visit到用户行
关于使用 LEFT JOIN、GROUP BY 和 ORDER BY 进行 MySQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8894096/