鉴于;
CREATE TABLE T1 (ID INTEGER, DESCRIPTION VARCHAR2(20));
INSERT INTO T1 VALUES (1,'ONE');
INSERT INTO T1 VALUES (2,'TWO');
INSERT INTO T1 VALUES (3,'THREE');
INSERT INTO T1 VALUES (4,'FOUR');
INSERT INTO T1 VALUES (5,'FIVE');
COMMIT;
为什么;
SELECT * FROM
( SELECT ROWNUM, ID, DESCRIPTION
FROM T1)
WHERE MOD(ROWNUM,1)=0;
返回
ROWNUM ID DESCRIPTION
------ -------------------------------------- --------------------
1 1 ONE
2 2 TWO
3 3 THREE
4 4 FOUR
5 5 FIVE
鉴于;
SELECT * FROM
( SELECT ROWNUM, ID, DESCRIPTION
FROM T1)
WHERE MOD(ROWNUM,2)=0;
返回零行???
困惑,预计ROWNUM =(2,4)将被退回......
答案 0 :(得分:1)
SELECT B.* FROM
( SELECT ROWNUM a, ID, DESCRIPTION
FROM T1) B
WHERE MOD(A,2)=0;
原因:您的方法涉及两次运行rownum。你不需要;你真的不想。根据操作顺序,where子句将在外部select之前执行;这意味着select尚未确定每行的值,并且行数尚未知晓。
其他:
我建议在内联视图中添加一个订单,以便rownumber按照预期的特定顺序而不是引擎派生的顺序。
答案 1 :(得分:1)
ROWNUM 的 2 操作。
第1个ROWNUM生成数字1到5
第二个ROWNUM不生成任何内容,因为对于ROWNUM值为1的行,但由于MOD(1,2)=0
为false,因此未输出记录且ROWNUM没有递增,一次又一次地使条件失败。
此查询使用别名,准确返回您所期望的内容:
SELECT * FROM
( SELECT ROWNUM as rn, ID, DESCRIPTION
FROM T1)
WHERE MOD(rn,2)=0;
答案 2 :(得分:0)
关于Oracle中ROWNUM
伪列的一些事实:
ROWNUM
由Oracle从数据库中检索行的顺序决定。ROWNUM
分配给行的顺序不一定与order by子句的顺序相关(order by子句可能会影响ROWNUM
顺序,因为它可能会导致不同的查询计划使用,但ROWNUM
bers不太可能与排序顺序匹配。)ROWNUM
子句过滤后,WHERE
bers被分配,因此如果您过滤掉ROWNUM
1,则永远不会返回任何记录。ROWNUM
列的子查询是有效的,因为在外部查询过滤行之前,整个子查询将返回到外部查询,但ROWNUM
仍将具有非确定性顺序要以确定的方式成功返回前N行或第N行查询,您需要以确定的方式分配行号。一种方法是使用`ROW_NUMBER'子查询中的分析函数:
select * from
(select ROW_NUMBER() over (order by ID) rn
, ID
, DESCRIPTION
from T1)
where rn <= 4 -- Top N
或
where rn = 4 -- 1st Nth row
甚至
WHERE MOD(rn,2)=0 -- every Nth row
在任何一种情况下,ORDER BY
分析函数中的ROW_NUMBER
子句都需要匹配数据的粒度,否则排序中的关系将再次是非确定性的,很可能与当前{{1}匹配订购。