2016-01-30 3 views
-1

Что случилось с row_number при использовании в подзапросе.ROW_NUMBER Sub Query

Если я запустил код изолированно, то его штраф, но как только я использую его в подзапросе, возвращаются неправильные результаты.

SELECT L.CALC1, X.APP_ID, L.CALC2, 
,ROW_NUMBER() OVER (PARTITION BY X.APP_ID ORDER BY CALC2 DESC) R 
FROM DWH_DEV.APP_CALC_REF X 
CAPD_DEV.APP_LOG L 
WHERE X.CALC_ID = L.CALC_ID 
AND X.APP_ID = 1234; 

Правильные результаты:

CALC1 APP_ID CAL2 R 
1 1234 54321 1 
1 1234 34322 2 
1 1234 23123 3 

SELECT CALC1, APP_ID, CALC2 FROM 
(
SELECT L.CALC1, L.CALC2, X.APP_ID 
,ROW_NUMBER() OVER (PARTITION BY X.APP_ID ORDER BY CALC2 DESC) R 
FROM DWH_DEV.APP_CALC_REF X 
CAPD_DEV.APP_LOG L 
WHERE X.CALC_ID = L.CALC_ID 
) WHERE R = 1 
AND APP_ID = 1234; 

Неправильные результаты:

CALC1 APP_ID CAL2 R 
1 1234 23123 1 

У меня есть решение, но зачем мне нужно использовать его?

SELECT CALC1, APP_ID, CALC2 FROM 
(
SELECT L.CALC1, L.CALC2, X.APP_ID 
,'MAX_' || ROW_NUMBER() OVER (PARTITION BY X.APP_ID ORDER BY CALC2 DESC) R 
FROM DWH_DEV.APP_CALC_REF X 
CAPD_DEV.APP_LOG L 
WHERE X.CALC_ID = L.CALC_ID 
) WHERE R = 'MAX_1' 
AND APP_ID = 1234; 

Правильные результаты:

CALC1 APP_ID CAL2 R 
1 1234 54321 1 

Приветствия

C

Oracle версия =

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64-разрядные производства PL/SQL Release 12.1.0.2.0 - Производство "CORE 12.1.0.2.0 Production" TNS для Linux: версия 12.1.0.2.0 - Производство NLSRTL Версия 12.1.0.2.0 - Производство

+1

Вы показали нам запрос с 'X.APP_ID = 1234' в WHERE условие, но результат содержит APP_ID = 54321, 34322 и 23123? Не могли бы вы объяснить это? – krokodilko

+0

Привет, я сделал задницу, чтобы напечатать мой вопрос. Я сделал поправку. Cheers –

+0

Вы имели в виду ваш row_number для упорядочения по 'calc_2 desc', так как' calc_1' одинаково для всех трех строк? Результат, который вы получаете, на самом деле не так, просто неопределен. –

ответ

1

Похоже, ваш запрос не является детерминированным. Результаты, которые вы получите, зависят от выбора оптимизатора пути доступа (сканирование таблицы, сканирование индекса и т. Д.)

См. Следующий пример (на основе схемы HR).

Установка:

create table rn_test 
as 
select * from employees; 

create index rn_test_ix on rn_test(job_id); 

Test1

select /*+ INDEX(rn_test) */ employee_id, job_id, row_number() over(order by job_id) rn 
from rn_test; 

Тест 2

select /*+ FULL(rn_test) */ employee_id, job_id, row_number() over(order by job_id) rn 
from rn_test; 

RESU л 1:

206 AC_ACCOUNT 1 
205 AC_MGR 2 
200 AD_ASST 3 
100 AD_PRES 4 
101 AD_VP 5 
102 AD_VP 6 
109 FI_ACCOUNT 7 
113 FI_ACCOUNT 8 
110 FI_ACCOUNT 9 
.... 

Результат 2:

206 AC_ACCOUNT 1 
205 AC_MGR 2 
200 AD_ASST 3 
100 AD_PRES 4 
102 AD_VP 5 
101 AD_VP 6 
110 FI_ACCOUNT 7 
109 FI_ACCOUNT 8 
113 FI_ACCOUNT 9 
... 
+0

спасибо, я посмотрю на это, когда вернусь в офис и обновляюсь с результатами. ура –