How to make a join between two tables but limiting to the first row that meets the join condition ?
In this simple example, I would like to get for every row in table_A the first row from table_B that satisfies the condition :
select table_A.id, table_A.name, table_B.city
from table_A join table_B
on table_A.id = table_B.id2
where ..
table_A (id, name)
1, John
2, Marc
table_B (id2, city)
1, New York
1, Toronto
2, Boston
The output would be:
1, John, New York
2, Marc, Boston
May be Oracle provides such a function (performance is a concern).
On Oracle12c there finally is the new cross/outer apply operator that will allow what you asked for without any workaround.
the following is an example that looks on dictionary views for just one of the (probably)many objects owned by those users having their name starting with 'SYS':
On Oracle 11g and prior versions you should only use workarounds that generally full scan the second table based on IDs of the second table to get the same results, but for testing puposes you may enable the lateral operator (also available on 12c without need of enabling new stuff) and use this other one
Query:
Outputs:
This solution uses the whole table, like in a regular join, but limits to the first row. I am posting this because for me the other solutions were not sufficient because they use one field only, or they have performance issues with large tables. I am no expert at Oracle so if someone can improve this please do so, I will be happy to use your version.
If you want just single value a scalar subquery can be used:
The key word here is FIRST. You can use analytic function
FIRST_VALUE
or aggregate constructFIRST
.For
FIRST
orLAST
the performance is never worse and frequently better than the equivalentFIRST_VALUE
orLAST_VALUE
construct because we don't have a superfluous window sort and as a consequence a lower execution cost:Since 12c introduced operator
LATERAL
, as well asCROSS/OUTER APPLY
joins, make it possible to use a correlated subquery on right side ofJOIN
clause: