2013-02-21 70 views
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 

什么是重写上面的SQL语句更清晰的方式的最佳途径......的Oracle SQL语句改写

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

select orderid 
    from myorders 
where rownum between 84 and 86 
+5

如果你没有在桌子上应用任何排序,那么在第84到86行没有意义......你在这里想达到什么目的? – haki 2013-02-21 17:15:45

+0

第二种解决方案中的ordertype和orderstatus怎么样? – 2013-02-21 17:16:42

+0

我什至不知道你的第一个查询将如何编译,因为你从一个不包含它的子查询中选择rownum。 – 2013-02-21 17:17:06

回答

2

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

select orderid 
from (SELECT orderid, rownum r 
     FROM myorders 
     WHERE ordertype = 'E' AND orderstatus = 'A' 
     ) a 
where r = 85 
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中嵌套的一个水平,甲骨文预计将支持ANSI FETCHOFFSET关键字来简化语法远一点。

0

如果您正在处理单个表格。

SELECT orderid 
FROM myorders 
WHERE ordertype = 'E' 
AND orderstatus = 'A' 
AND rownum between 84 and 86 
+0

由于'rownum'伪列的生成方式,它永远不会返回任何值。这是解释[在一个老问题的答案](http://stackoverflow.com/a/855446/266304)。 – 2013-02-21 17:47:02

+0

@JParadiso - 我同意亚历克斯·普尔 - 因为ROWNUM的性质,这永远不会返回任何东西。你应该测试你的例子。以下是测试:SELECT empno FROM scott.emp WHERE rownum介于5和10之间 – Art 2013-02-21 20:18:04

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 
/