Разница при использовании ROWNUM - PullRequest
5 голосов
/ 16 августа 2011

Я ищу поисковый запрос 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

Кажется, второй тоже работает. Есть ли различия в производительности между этими двумя запросами?

Ответы [ 2 ]

4 голосов
/ 16 августа 2011

Проблема в том, что вы фильтруете в том же запросе, что и ROWNUM. Следовательно, причина, по которой вы должны иметь подзапрос, сначала сгенерировать rownum, а затем применить фильтрацию. Почему BETWEEN работает нормально, вероятно, является некоторым нюансом того, как движок обрабатывает запрос, но я бы опасался, что он не всегда будет давать правильные результаты. Так что дело не в производительности, а в том, чтобы действительно получать правильные результаты.

Эта статья объясняет, почему вы должны поставить больше, чем за пределами подзапроса: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns009.htm

SELECT * FROM employees
    WHERE ROWNUM > 1;

"Первой извлеченной строке присваивается ROWNUM, равный 1, и условие становится ложным. Вторая извлекаемая строка теперь является первой строкой, а также присваивается значение ROWNUM, равное 1, и делает условие ложным. Все строки впоследствии не могут выполнить выполнить условие, поэтому строки не возвращаются. "

4 голосов
/ 16 августа 2011

Правильный способ использования ROWNUM:

SELECT x.* 
  FROM (SELECT t.*, 
               ROWNUM rn 
          FROM tableName t) AS x
 WHERE x.rn > 100
   AND x.rn < 200

BETWEEN включительно, поэтому два запроса не идентичны логике.

Для получения дополнительной информации о ROWNUM см. эту ссылку (включает ссылку на документацию Oracle .

...