Вы можете использовать аналитические функции , чтобы избежать ударов по каждой таблице (или, в частности, B
) более одного раза
Использование CTE для предоставления фиктивных данных для A
и B
васможно сделать это:
with A as (
select 1 as id from dual
union all select 2 from dual
union all select 3 from dual
),
B as (
select 1 as a_id, date '2012-01-01' as created_date, 'First for 1' as value
from dual
union all select 1, date '2012-01-02', 'Second for 1' from dual
union all select 1, date '2012-01-03', 'Third for 1' from dual
union all select 2, date '2012-02-01', 'First for 2' from dual
union all select 2, date '2012-02-03', 'Second for 2' from dual
union all select 3, date '2012-02-01', 'First for 3' from dual
union all select 3, date '2012-02-03', 'Second for 3' from dual
union all select 3, date '2012-02-05', 'Third for 3' from dual
union all select 3, date '2012-02-09', 'Fourth for 3' from dual
)
select id, created_date, value from (
select a.id, b.created_date, b.value,
row_number() over (partition by a.id order by b.created_date desc) as rn
from a
join b on b.a_id = a.id
)
where rn = 1
order by id;
ID CREATED_D VALUE
---------- --------- ------------
1 03-JAN-12 Third for 1
2 03-FEB-12 Second for 2
3 09-FEB-12 Fourth for 3
Вы можете выбрать любые столбцы, которые вы хотите, из A
и B
, но вам нужно будет псевдоним их в подзапросе, если есть какие-либо с одинаковыми именами в обоихтаблицы.
Вам также может потребоваться пользователь rank()
или dense_rank()
вместо row_number
для надлежащей обработки связей, если вы можете иметь дочерние записи с той же датой создания.