如何实现Top-N排行榜和分页查询

你好,当我第一次接手旧系统时,排序和迁移 SQL 页面确实是一个令人头疼的问题。
你的总结已经完全完成了。
我会告诉你我经历过的陷阱,它们都是真实的。

当年我们的系统用的是Oracle 1 1 g,数据量非常大,员工有几千人。
一旦我们开始研究 Top-N,问题就出现了。

看看这篇文章: SQL 选择员工姓名、工资 来自员工 其中 ronome <= 5 按Salary DESC排序;
我当时就傻眼了。
为什么工资最高的人排名一到五,而不是前五?后来发现是先指定ROWNUM,然后编号。
如果这样写的话,第一个输入的数据就是ROWNUM 1 ,如果满足<=5 则直接选择。
是的,它改变了: SQL 选择员工姓名、工资 从 ( SELECT emp_name,salary,ROWNUM as rn 来自员工 按工资 DESC 排序 ) 其中 rn <= 5 ;
这次是真的。
我还尝试了子查询方法来查找第三高的工资: SQL 选择员工姓名、工资 来自员工 其中工资 = ( 选择薪资 来自员工 按工资 DESC 排序 限制 1 偏移 2 );
这种写法在MySQL上效果很好,但是当数据量很大时,查询特别慢。
后来查资料发现每次都要运行排序子查询,效率低下。
后来改为: SQL 选择员工姓名、工资 来自员工 e1 它在哪里( 选择1 来自员工 e2 其中 e2 .salary > e1 .salary 并且罗诺姆 <= 2 );
这次快了很多,至少在我们的环境中是这样。

页码更烦人。
当我第一次来这里的时候,我有一个报告,我想按月份过滤它,所以我使用了OFFSET。
太多的数据会导致缓慢死亡。
我也用你的Oracle FETCH FIRST,但是我总是忘记在开头输入OFFSET,这会导致结果集为空,让用户惊慌失措。
后来我规范了自己的写法,加了注释,强制检查,所以没有出现严重错误。

MySQL的LIMIT工作得很好,但是一旦我们租用的服务器数据库崩溃了,所有数据都消失了,剩下的就只有LIMIT操作的缓存了。
结果,用户询问为什么上一页的数据消失了。
后来添加了定时备份策略,就不再出现这个问题了。

最大的问题是SQL Server同事。
他们以不同的方式使用和编写 TOP: SQL -
写作1 选择前 5 位 emp_name,按薪资 DESC 排序的员工薪资;
-
写 2 SELECT emp_name, SALARY FROM EMPLOYEE ORDER BY SALARY DESC OFFSET 0 ROWS FETCH 5 ROWS ONLY;
当时看的时候很困惑,后来发现他们老版本里用的是TOP,我觉得很简单。
我建议他们使用 FETCH 来标准化模式。

总结一下我的缺点: 1 、Oracle ROWNUM使用错误,导致Top-N排名反向。
2 . 查找名称N的子查询效率较低,因此使用EXISTS优化。
3 . 如果迁移时忘记了偏移量,用户会惊死。
4 .我的老SQL Server同事坚持使用TOP,导致写法不一样。

你写的真全面。
我已经尝试过所有这些。
你所要做的就是根据数据库选择正确的招式,不要盲目使用。
尤其是当数据量很大时,效率就很关键。

SQL--over()开窗函数的应用

底线:OVER() 窗口函数是一个功能强大的 SQL 工具,允许您在不减少行数的情况下执行分组计算。

分组排序:按产品ID分组,按修改日期排序,使用RANK()获取排名,并查找最新记录。

累计计算:按日期分组,统计交易笔数和累计金额。

移动计算:7 天移动平均销售额。
使用 ROWSBETWEEN 定义窗口。

注意:OVER()后面是一个函数,所以在分割大量数据时要小心。

自己掂量一下。

用sql语句,查询每个班级成绩排名前三名的学生姓名

嗯... SQL Server... 2 02 2 年... 我正在做这个... 有一个表... 比如叫Employees... 里面有个名字列... 有两个数据项... 一个是“李张三”... 另一个是“王三张”... 对... 这时候我要检查... 包含“张”字... 不能直接写 SELECT FROMEmployees WHERE Name = "Zhang"... 这肯定不行... 看... 这样写... return 是空的...我当时一头雾水...数据明明就在那里...
后来才知道必须用LIKE...嗯...LIKE关键字...没错...就像你说的...SELECT FROMEmployees WHERE Name LIKE '%张%'...这样写...查询条件中...%是通配符...前面加一个%...最后加一个%...也就是说...可以是'张'之前和之后的所有内容...或者什么都没有...全是嗯...所以'李张三'和'王三张'...可以查到...这个金额...比如你的表里有1 00条数据...用这个LIKE...查一下...比如6 0条...那么6 0条...查一下要花多少钱...查数据项的数量...不是金额...
看...如果只是在前面加一个%...比如name LIKE '%张'...那么就只能是有姓张……长啥样? '张三'...'张伟'...这个...但是'李张三'...找不到...所以你必须添加...前后...否则...搜索不完整...这...可能我有点极端...那就是...用LIKE搜索这个...一定要记住...通配符%...必须放在两边...别忘了...否则结果会错...错了...