我在网上搜索Oracle分页查询,其中大部分都告诉我将查询包装两次:
SELECT *
FROM (SELECT t.*, ROWNUM rn
FROM tableName t
WHERE ROWNUM < 200)
WHERE rn > 100
只是想知道我是否可以输入:
SELECT *, ROWNUM rn
FROM tableName t
WHERE ROWNUN BETWEEN 100 AND 200
似乎第二个也适用。这两个查询之间是否存在(性能)差异?
答案 0 :(得分:4)
使用ROWNUM的正确方法是:
SELECT x.*
FROM (SELECT t.*,
ROWNUM rn
FROM tableName t) AS x
WHERE x.rn > 100
AND x.rn < 200
BETWEEN
是包容性的,因此这两个查询的逻辑并不相同。
有关ROWNUM的更多信息,请参阅this link (includes link to Oracle documentation。
答案 1 :(得分:4)
问题是您正在使用生成ROWNUM的同一查询进行过滤。因此,您必须首先生成rownum然后应用过滤的子查询的原因。为什么BETWEEN工作正常可能是引擎处理查询的一些细微差别,但我会警惕它可能不会始终如一地给你正确的结果。所以这不是性能问题,因为这是实际得到正确结果的问题。
本文解释了为什么必须将大于子查询放在外部: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns009.htm
SELECT * FROM employees
WHERE ROWNUM > 1;
“获取的第一行被赋予ROWNUM为1并使条件为false。要获取的第二行现在是第一行,并且还被赋予ROWNUM为1并使条件为false。所有行随后都无法满足条件,因此不返回任何行。“