ROW_NUMBER子查询

时间:2016-01-30 20:08:51

标签: oracle

在子查询中使用row_number时出了什么问题。

如果我单独运行代码就可以了,但是一旦我在子查询中使用它,就会返回错误的结果。

True

正确的结果:

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;

干杯

C

Oracle版本=

Oracle Database 12c企业版12.1.0.2.0版 - 64位生产 PL / SQL版本12.1.0.2.0 - 生产 "核心12.1.0.2.0生产" 适用于Linux的TNS:版本12.1.0.2.0 - 生产 NLSRTL版本12.1.0.2.0 - 生产

1 个答案:

答案 0 :(得分:1)

看起来您的查询不具有确定性。您将获得的结果取决于访问路径优化器选择(表扫描,索引扫描等)

参见以下示例(基于HR模式)。

<强>设定:

create table rn_test
as
select * from employees;

create index rn_test_ix on rn_test(job_id);

<强>测试1

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;

结果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
...