使用mod函数的Oracle rownum行为

时间:2012-08-22 19:14:22

标签: sql oracle

鉴于

CREATE TABLE Foo(v1 integer, v2 integer);

INSERT INTO Foo VALUES (1,2);
INSERT INTO Foo VALUES (3,4);
INSERT INTO Foo VALUES (5,6);

SELECT COUNT(*) FROM Foo WHERE mod(rownum,2) = 0;

返回0行,它应该返回1

SELECT COUNT(*) FROM (SELECT mod(rownum,2) z FROM Foo) tt WHERE z=0;

返回1行

我在这里缺少什么?我在ROWNUM或MOD文档中没有看到任何暗示任何想法的内容。

2 个答案:

答案 0 :(得分:7)

在您查询之前,

ROWNUM未分配,因此您无法在WHERE子句中使用它。

您可以执行以下操作:

SELECT COUNT(*) 
FROM
(
  select v1, v2, rownum rn
  from Foo 
) f
WHERE mod(rn,2) = 0;

ROWNUM是结果集中行的位置,并在选择记录后进行评估。

这些类型的查询永远不会起作用:

WHERE ROWNUM > x
WHERE ROWNUM BETWEEN x AND y

但这会起作用

WHERE ROWNUM < x

由于您希望使用rownum功能评估mod,因此rownum在此时无法使用,因此无效。这就是为什么你必须将它放在子查询中才能使用mod函数。

答案 1 :(得分:2)

ROWNUM返回实际查询的行号,而不是查询基于的表的行号。因此SELECT COUNT(*) ...返回带有mod(rownum,2) != 0的rownumber 1的一行,然后WHERE caluse将其丢弃,实际上根本不返回任何行。

(未过滤的)子选择将rownumber作为列返回可以提供帮助。然后将WHERE子句应用于外部选择。