這是因爲rownum
的特殊性。這是一個pseudo-column,它應用於查詢返回的結果集。 (這就是爲什麼WHERE ROWNUM > 1
始終爲false)
在這種情況下,使用ROWNUM會導致查詢在WHERE子句返回false時停止。因此,這不返回行(因爲0只偶數行返回):
select * from employee a
where 0 = mod(rownum,2);
你的第二個方法有哪些未在WHERE子句中使用ROWNUM的子查詢,因此使整個表是在外部查詢中返回進行評估。
任何允許在不評估ROWNUM的情況下實現整個結果集的方法都可行。這也將產生你想要的結果:
select * from
(select a.*, rownum as rn from employee a)
where mod(rn,2) = 1
/
由於@DavidAldridge在他的評論中指出的,沒有ORDER BY子句的結果集是隨機的。 ROWNUM對ORDER BY沒有好處,所以爲了保證排序使用分析函數ROW_NUMBER()代替。
select * from
(select a.*
, row_number() over (order by a.emp_id) as rn
from employee a)
where mod(rn,2) = 0
/
「如何波紋管查詢獲取從表中只有前兩個的記錄。」
通過COUNT STOPKEY
操作的奇蹟。該查詢知道預計有多少行;它返回行(並分配ROWNUM的值),直到達到該限制。
我們可以在EXPLAIN PLAN中看到這個。沒有過濾器:
SQL> explain plan for
2 select * from emp;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 111 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 3 | 111 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
12 rows selected.
SQL>
這是計劃where rownum <= 2
。請注意所選行的區別:
SQL> explain plan for
2 select * from emp
3 where rownum <= 2;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1973284518
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 74 | 3 (0)| 00:00:01 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | TABLE ACCESS FULL| EMP | 3 | 111 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=2)
Note
-----
- dynamic sampling used for this statement (level=2)
18 rows selected.
SQL>
來源
2015-04-19 13:53:38
APC
您應該注意,表中的行必須被視爲沒有順序,除非由數據定義,因此您需要ORDER BY子句才能使其具有意義。 –