Reputation: 1
I have a query where in I have to sort the table and retrieve the first value that matches for every id.
The scenario that I would like to achieve is to get the ID of Table A that matches the first ID_2 from the sorted Table B
I have a slight concept of the code.
select A.ID, A.COL1, B.COL1, B.COL2
from A, B
where A.ID = B.ID
and B.ID_2 = (select ID_2
from (select ID_2
from B B2
where B2.ID = A.ID
order by (case when B2.PRIO ...))
where rownum = 1)
The problem here is A.ID is not accessible within the select in where clause.
Another way that I found was using analytic function
select ID, COL1, COL2
from (select A.ID, A.COL1, B.COL2,
row_number() over (partition by A.ID order by (case when B.PRIO ...) row_num
from A, B
where A.ID = B.ID)
where row_num = 1
The problem with this code is I think it is not good performance wise.
Can anyone help me? =)
Upvotes: 0
Views: 684
Reputation:
You don't need a correlated sub-subquery (which is invalid in Oracle), and you don't need an analytic function either. You need the aggregate first/last
function.
... and b.id_2 = (select max(id_2) keep (dense_rank first order by case.....)
from b b2
where b2.id = a.id
) .....
Even this is probably too complicated. If you would describe your requirement (instead of just posting some incomplete code), the community may be able to help you simplify the query even further.
Upvotes: 0
Reputation: 1270653
row_number()
is not a statistic function. It is an analytic or window function. It is probably your best bet. I would do:
select a.*
from A join
(select b.*,
row_number() over (partition by b.ID order by (case when b.PRIO ...) as seqnum
from b
) b
on A.ID = B.ID and b.seqnum = 1;
If you really only want A.ID
, then you don't need A
at all . . . the information is in B.ID
(assuming it is not being used for filtering). The above then simplifies to:
select b.id
from (select b.*,
row_number() over (partition by b.ID order by (case when b.PRIO ...) as seqnum
from b
) b
where b.seqnum = 1;
Upvotes: 1