The following query should return all not-null values for column n.c
because C
is not nullable.
select distinct A, B, a.C, n.C
from o
outer apply ( -- Get first C which Status = 1, if there is any
select C
from o i where i.A = o.A and i.B = o.B and STATUS = 1 and ROWNUM = 1) a
outer apply ( -- Get the latest C otherwise (ID is identity column)
select C
from o i where i.A = o.A and i.B = o.B and ROWNUM = 1
order by ID desc) n
However, n.C
will be null if a.C
is null. And it will return the desired value if I remove the outer apply of a
.
select distinct A, B, n.C
from o
outer apply (
select C
from o i where i.A = o.A and i.B = o.B and ROWNUM = 1
order by ID desc) n
Is it a bug of Oracle?
BTW, it works as expected if I switch two outer apply
?
select distinct A, B, a.C, n.C
from o
outer apply (
select C
from o i where i.A = o.A and i.B = o.B and ROWNUM = 1
order by ID desc) n
outer apply (
select C
from o i where i.A = o.A and i.B = o.B and STATUS = 1 and ROWNUM = 1) a
Oracle version
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production PL/SQL Release 12.1.0.2.0 - Production CORE 12.1.0.2.0 Production TNS for Linux: Version 12.1.0.2.0 - Production NLSRTL Version 12.1.0.2.0 - Production
Test data
CN
of 2
, 2
is null:
with o(ID, A, B, C, Status) as (
select 1, 1, 1, 1, 1 from dual union all
select 2, 2, 2, 2, 0 from dual union all
select 3, 2, 2, 2, 0 from dual
)
select distinct A, B, a.C Ca, n.C Cn
from o
outer apply ( -- Get first C which Status = 1, if there is any
select C
from o i where i.A = o.A and i.B = o.B and STATUS = 1 and ROWNUM = 1) a
outer apply ( -- Get the latest C otherwise (ID is identity column)
select C
from o i where i.A = o.A and i.B = o.B and ROWNUM = 1
order by ID desc) n
returns
A B CA CN 1 1 1 1 2 2 NULL NULL
CN
of 2
, 2
is not null after moved outer apply (...) n
:
with o(ID, A, B, C, Status) as (
select 1, 1, 1, 1, 1 from dual union all
select 2, 2, 2, 2, 0 from dual union all
select 3, 2, 2, 2, 0 from dual
)
select distinct A, B, a.C Ca, n.C Cn
from o
outer apply ( -- Get the latest C otherwise (ID is identity column)
select C
from o i where i.A = o.A and i.B = o.B and ROWNUM = 1
order by ID desc) n
outer apply ( -- Get first C which Status = 1, if there is any
select C
from o i where i.A = o.A and i.B = o.B and STATUS = 1 and ROWNUM = 1) a
returns
A B CA CN 1 1 1 1 2 2 NULL 2
And the following query (which try to make ROWNUM more determind) still got the wrong result.
with o(ID, A, B, C, Status) as (
select 1, 1, 1, 1, 1 from dual union all
select 2, 2, 2, 2, 0 from dual union all
select 3, 2, 2, 2, 0 from dual
)
select distinct A, B, a.C Ca, n.C Cn
from o
outer apply ( -- Get first C which Status = 1, if there is any
select C
from o i where i.A = o.A and i.B = o.B and STATUS = 1 and ROWNUM = 1) a
outer apply ( -- Get the latest C otherwise (ID is identity column)
select * from (
select C
from o i where i.A = o.A and i.B = o.B
order by ID desc) x
where ROWNUM = 1) n