一道朋友分享的关于mysql的面试题( 二 )


■网友
能做是能做,但是这种SQL从来都是一不小心就能把数据库跑挂了的那种,其实是不建议使用的……select * from logs as t1 where (select count(*) from logs as t2 where t2.userid = t1.userid and t2.createtime \u0026gt;= t1.createtime and t2.id \u0026gt;= t1.id) \u0026lt;= 3;对每条记录,查找所有userid与自己相等且创建时间比自己晚(其实建议是使用递增的id而不是时间,时间精度不够)的记录,这是个全表扫描的查询,添加一个(userid, createtime)(或者(userid, id))的索引,勉强可以让子查询不要再进行全表扫描,姑且算是可以用吧。
■网友
跟leetcode的Department Top Three Salaries差不多,可以去讨论区看看。贴一个比 @灵剑 那个版本稍快的:SELECT l1.userid , l1.time , l1.contentFROM log l1LEFT JOIN log l2ON l1.userid = l2.userid AND l1.time \u0026lt; l2.timeGROUP BY l1.idHAVING COUNT(l2.id) \u0026lt; 3;但是存在两个不足:1. 要求数据表必须有主键;2. time如果存在重复的话,结果中某些用户的日志数量可能会超过3条。@Litrin 的变量版本也挺有意思,但是我感觉有些细节不对,修改后:SELECT l2.userid , l2.time , l2.contentFROM ( SELECT l1.* , IF(@prev = l1.userid, @rank := @rank + 1, @rank := 1) AS rn , @prev := l1.userid FROM log l1 JOIN ( SELECT @prev := NULL ) init ORDER BY l1.userid , l1.time DESC) l2WHERE l2.rn \u0026lt;= 3;
■网友
分析函数或者窗口函数(pg和oracle)中不同的叫法,又是一个mysql不支持很多人觉得没用的功能


推荐阅读