0
SELECT orderid 
 FROM (SELECT orderid, rownum r 
         FROM (SELECT orderid 
                 FROM myorders 
                WHERE ordertype = 'E' 
                  AND orderstatus = 'A') a 
         WHERE rownum < 86) 
 WHERE r > 84

以更清晰的方式重写 ABOVE sql 语句的最佳方法是什么...

我尝试了以下方法,但没有得到任何结果。

select orderid 
  from myorders 
 where rownum between 84 and 86
4

4 回答 4

3

假设您正在尝试生成数据页,并假设您希望如果表中的数据没有变化,结果是稳定且一致的(内部查询中的每一行都在结果的一页上返回您改变上限和下限),最有效的方法基本上就是您最初发布的方法。但是您确实需要ORDER BY在内部查询中添加一个。否则,Oracle 在每一页上返回一行数据或从不在任何页上返回一行是完全正确的

SELECT orderid 
 FROM (SELECT orderid, rownum r 
         FROM (SELECT orderid 
                 FROM myorders 
                WHERE ordertype = 'E' 
                  AND orderstatus = 'A'
                ORDER BY <<something>>) a 
         WHERE rownum < 86) 
 WHERE r > 84

如果您真的更关心可读性而不是性能,您可以通过执行类似的操作将其减少一级嵌套

SELECT orderid
  FROM (SELECT orderid, 
               rank() over (order by <<something>>) rnk
          FROM myorders
         WHERE ordertype = 'E'
           AND orderstatus = 'A')
 WHERE rnk > 84
   AND rnk < 86

在 Oracle 12c 中,Oracle 有望支持 ANSIFETCHOFFSET关键字以进一步简化语法。

于 2013-02-21T17:23:51.963 回答
2

缩进是第一个建议。但是您可以消除一组子查询:

 select orderid
 from (SELECT orderid, rownum r
        FROM myorders
        WHERE ordertype = 'E' AND orderstatus = 'A'
       ) a
 where r = 85
于 2013-02-21T17:16:18.440 回答
0

如果您正在处理单个表。

SELECT orderid
FROM   myorders 
WHERE  ordertype = 'E' 
AND    orderstatus = 'A'
AND    rownum between 84 and 86
于 2013-02-21T17:37:13.437 回答
0

另外在行之间进行选择的一般示例。在我个人看来,使用 ROW_NUMBER() 而不是 ROWNUM 会更好也更明智。他们是compl。不同的...:

-- Between rows --
SELECT * FROM 
     ( SELECT deptno, ename, sal
            , ROW_NUMBER() OVER (ORDER BY ename) row_seq 
  FROM scott.emp)
 WHERE row_seq BETWEEN 5 and 10
 /
于 2013-02-21T20:14:49.910 回答