2014-01-31 2 views
1

почему ниже запрос не дает результатов, если я удаляю знак < из запроса. Потому что даже без < он должен совпадать с результатами?oracle sql wih rownum <=

Запрос используется для получения второго значения макс ID:

select min(id) 
from(
    select distinct id 
    from student 
    order by id desc 
) 
where rownum <=2 


student id 
1 
2 
3 
4 

ответ

6

RowNum имеет особое значение в Oracle. Он увеличивается с каждой строкой, но оптимизатор знает, что увеличивается непрерывно, и все последовательные строки должны соответствовать условию rownum. Поэтому, если вы укажете rownum = 2, это никогда не произойдет, поскольку первая строка уже отклонена.

Вы можете увидеть это очень приятно, если вы поплатите свой запрос по вашему запросу. Он покажет что-то вроде:

плана для rownum <=:

COUNT STOPKEY  

план для rownum =:

FILTER 
+0

Спасибо, что это действительно полезно. – sunleo

+0

Добро пожаловать. BTW: вам нужно самое высокое значение, но одно (так всегда меньше максимального) или только вторая строка? –

0

Почему бы просто не использовать

select id 
from (select distinct id 
      ,  row_number() over (order by id desc) x 
      from student 
     ) 
where x = 2 

Или даже очень плохо. Получение счета и индекс :) ​​

select id 
from (select id 
      ,  row_number() over (order by id desc) idx 
      ,  sum(1) over (order by null) cnt 
      from student 
      group 
      by  id 
     ) 
where idx = cnt - 1 -- get the pre-last 

Или

where idx = cnt - 2 -- get the 2nd-last 

Или

where idx = 3 -- get the 3rd 
+0

спасибо за ответ.am, используя этот запрос как внутренний запрос, чтобы получить nth max и min, я хочу, почему без <он не работает. – sunleo

+0

Попробуйте еще раз. –

+0

См. Ответ GuidoLeenders. Он хорошо указывает, почему он так не работает. Проверьте мой запрос на фактическое решение. –

0

Заказать возр вместо убыв

select id from student where rownum <=2 order by id asc; 
1

Значение ROWNUM не назначается постоянно в строке (это обычное заблуждение). Строка в таблице не имеет числа; вы не можете запрашивать строки 2 или 3 из таблицы нажмите Here для получения дополнительной информации.

Это из указанной ссылке:

Также в заблуждение многих людей, когда значение ROWNUM фактически назначен. Значение ROWNUM присваивается строке после прохождения фазы предиката запроса, но до того, как запрос выполнит какую-либо сортировку или агрегацию. Кроме того, значение ROWNUM увеличивается только после того, как он назначен, поэтому следующий запрос никогда не будет возвращать строку:

select * 
from t 
where ROWNUM > 1; 

Поскольку ROWNUM> 1 не верно для первой строки, ROWNUM не продвигается до 2 Следовательно, ни одно значение ROWNUM никогда не будет больше 1.Рассмотрим запрос с этой структурой:

select ..., ROWNUM 
from t 
where <where clause> 
group by <columns> 
having <having clause> 
order by <columns>; 
1

Я думаю, что это вопрос вы ищете:

select id 
from (select distinct id 
     from student 
     order by id desc 
    ) t 
where rownum <= 2; 

Oracle обрабатывает rownum перед order by, так что вам нужно подзапрос, чтобы получить первые два строк. Команда min() вынуждала агрегацию, которая возвращала только один результат, но до применения rownum.

Если вы действительно хотите, только второе значение, то потребуется дополнительный слой подзапросов:

select min(id) 
from (select id 
     from (select distinct id 
      from student 
      order by id desc 
      ) t 
     where rownum <= 2 
    ) t; 

Однако, я хотел бы сделать:

select id 
from (select id, dense_rank() over (order by id) as seqnum 
     from student 
    ) t 
where seqnum = 2; 
0

Попробуйте

SELECT * 
FROM (
    SELECT id, row_number() over (order by id asc) row_num 
    FROM student 
    ) AS T 
WHERE row_num = 2 -- or 3 ... n 

ROW_NUMBER

Смежные вопросы