选择没有ROWNUM的前N行?
|
希望您能帮我做作业:)
我们需要构建一个查询,以输出前N名最高薪雇员。
我的版本运行正常。
例如前3名:
SELECT name, salary
FROM staff
WHERE salary IN ( SELECT *
FROM ( SELECT salary
FROM staff
ORDER BY salary DESC )
WHERE ROWNUM <= 3 )
ORDER BY salary DESC
;
请注意,这将输出前三名且工资相同的员工。
1:迈克(4080)
2:史蒂夫,2800
2:苏珊,2800
2:杰克,2800
3:克洛伊(1400)
但是现在我们的老师不允许我们使用ROWNUM
。
我到处搜寻,没有发现任何可用的内容。
我的第二个解决方案要感谢Justin Caves的提示。
首先我尝试了这个:
SELECT name, salary, ( rank() OVER ( ORDER BY salary DESC ) ) as myorder
FROM staff
WHERE myorder <= 3
;
错误消息是:\“ myorder:无效的标识符\”
多亏了DCookie,它现在很清楚了:
\“ [...]分析之后应用
计算where子句,其中
这就是为什么您会得到myorder的错误
是无效的标识符。\“
将SELECT包装起来即可解决此问题:
SELECT *
FROM ( SELECT name, salary, rank() OVER ( ORDER BY salary DESC ) as myorder FROM staff )
WHERE myorder <= 3
;
我的老师再次罢工,不允许使用这种奇特的分析功能。
@Justin Caves的第三个解决方案。
\“如果解析函数也
不允许,我可以选择另一个选项
想象-一个你永远不会
曾经,曾经实际写过,
就像\“
SELECT name, salary
FROM staff s1
WHERE (SELECT COUNT(*)
FROM staff s2
WHERE s1.salary < s2.salary) <= 3
没有找到相关结果
已邀请:
5 个回复
版萍层分
关于性能,我不会依赖查询计划中的COST号码,这只是一个估计,通常无法比较不同SQL语句的计划之间的成本。您最好查看查询实际执行的一致性获取数量,并考虑随着表中行数增加查询性能将如何扩展。第三个选项的效率将根本不如其他两个选项高,这仅仅是因为它需要扫描STAFF表两次。 我没有您的STAFF表,所以我将使用SCOTT模式中的EMP表 解析函数解决方案与ROWNUM解决方案实际上进行7个一致的获取
但是,COUNT(*)解决方案实际上执行了99次一致的获取,并且必须对表进行完全扫描两次,因此效率降低了10倍以上。随着表中行数的增加,伸缩性将大大恶化
辰炔诚薯
珊畴炮贩号
荆怖赡
时,排名相同的最高薪水将被视为平局。
功飘
(FETCH FIRST语法是Oracle 12c的新增功能)