如何正确使用Oracle Order by和ROWNUM?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

我很难将存储过程从SQL Server转换为Oracle,以使我们的产品与其兼容。

我有查询返回一些表的最新记录,基于时间戳:

SQL Server:

SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC

=>这将返回我最近的记录

但是oracle

SELECT *
FROM raceway_input_labo 
WHERE  rownum <= 1
ORDER BY t_stamp DESC

=>这将返回我最旧的记录(可能取决于索引),无论ORDER BY语句!

我用这种方式封装了Oracle查询以符合我的要求:

SELECT * 
FROM 
    (SELECT *
     FROM raceway_input_labo 
     ORDER BY t_stamp DESC)
WHERE  rownum <= 1

它的工作原理。但是对我来说这听起来像是一个可怕的黑客攻击,特别是如果我在涉及的表中有很多记录。

达到此目的的最佳方法是什么?

提问于
用户回答回答于

where声明被执行之前order by。所以,你想要的查询是“先取第一行然后按 t_stamp desc 排序 ”。这不是你想要的。

子查询方法是在Oracle中执行此操作的正确方法。

如果你想要一个可以在两台服务器上工作的版本,你可以使用:

select ril.*
from (select ril.*, row_number() over (order by t_stamp desc) as seqnum
      from raceway_input_labo ril
     ) ril
where seqnum = 1

外层*将在最后一列返回“1”。你需要单独列出列以避免这种情况。

用户回答回答于

SELECT * FROM (SELECT rownum, deptno, ename
           FROM scott.emp
        ORDER BY deptno
       )
 WHERE rownum <= 3
 /

ROWNUM    DEPTNO    ENAME
---------------------------
 7        10    CLARK
 14       10    MILLER
 9        10    KING


 SELECT * FROM 
 (
  SELECT deptno, ename
       , ROW_NUMBER() OVER (ORDER BY deptno) rno
  FROM scott.emp
 ORDER BY deptno
 )
WHERE rno <= 3
/

DEPTNO    ENAME    RNO
-------------------------
10    CLARK        1
10    MILLER       2
10    KING         3

扫码关注云+社区