Oracle rownum во внешнем запросе дает неверные результаты

у меня есть длинный запрос sql, который использует rownum, но дает неправильные значения. Ниже мой запрос:

Select *
FROM (  SELECT *
    FROM R this_
         LEFT OUTER JOIN TS
            ON this_.T1 = TS.T1
         LEFT OUTER JOIN T 
            ON TS.T2 = T.T2
         LEFT OUTER JOIN TS system4_
            ON T.SRC = system4_.system_id
         LEFT OUTER JOIN TS system6_
            ON T.TGT = system6_.system_id
         LEFT OUTER JOIN TS system7_
            ON touchpoint3_.INIT = system7_.system_id
         LEFT OUTER JOIN ST 
            ON TS_.SC = ST.SC
         LEFT OUTER JOIN RS 
            ON this_.status_id = RS.status_id
         LEFT OUTER JOIN client client5_                                             ONsystem4_.CLIENT_ID=client5_.CLIENT_ID                                  
   WHERE this_.status_id = 5
ORDER BY this_.ID --This is a column on R table
)WHERE ROWNUM <= 10

Но если я помещу rownum в такой подзапрос, я получу правильный вывод

WHERE this_.status_id = 5 and rownum<=10

Может ли кто-нибудь сказать мне, почему я получаю неправильный вывод с моим запросом?


person Nishant Shrivastava    schedule 10.07.2014    source источник
comment
Они оба действительные запросы - что вы подразумеваете под правильным/неправильным выводом? Вы вообще ничего не показали.   -  person Jeffrey Kemp    schedule 10.07.2014


Ответы (1)


Во внутреннем запросе проверка ROWNUM <= 10 будет выполнена до применения ORDER BY this_.ID, поэтому вы зависите от того, в каком порядке Oracle возвращает данные (возможно, в том порядке, в котором они появляются в любом индексе, используемом для доступа к ним.

Во внешнем запросе вы уже предоставили упорядоченный набор, поэтому результат фильтрации только первых 10 строк не обязательно будет таким же, поскольку порядок элементов при распределении номеров строк не одинаков.

Единственный раз, когда вы должны использовать ROWNUM для ограничения результатов запроса, это когда:

  1. вам все равно, какие строки вы получите обратно
  2. вы начинаете с упорядоченного набора результатов

Лучшим подходом для вашего требования, вероятно, будет использование RANK или DENSE_RANK аналитический функции.

Быстрый поиск в Google показывает, что есть несколько примеров как это сделать уже.

person ninesided    schedule 10.07.2014
comment
Вам нужно добавить row_number() в группу rank/dense_rank. - person vav; 10.07.2014