Meriton,
Этот подход использует вложенные встроенные представления. Я доказал этот подход на больших наборах данных, он работает очень хорошо.
Лучший способ понять запрос - начать с самого внутреннего "М" встроенного представления. Я добавил счет ради отладки и ясности. Это идентифицирует максимальный (т.е. самый последний ???) идентификатор адреса для каждого здания:
select maxa.b_id, max(maxa.a_id) a_id, count(*) c
from address maxa
group by maxa.b_id;
Следующее встроенное представление «A» использует вышеуказанное встроенное представление «M», чтобы решить, какой адрес получить, затем присоединяется к этому идентификатору адреса для возврата набора полей адреса:
select ma.b_id, ma.a_id, ma.addr1, ma.addr2, ma.addr3, m.c
from address ma,
( select maxa.b_id, max(maxa.a_id) a_id, count(*) c
from address maxa
group by maxa.b_id ) m
where ma.a_id = m.a_id;
Приведенное выше встроенное представление «A» доставляет преобразованный набор адресов к окончательному запросу. Принимая во внимание, что отношение между BUILDING и ADDRESS составляет от 1 до 0..n, отношение между BUILDING и "A" составляет от 1 до 0..1, основное внешнее соединение:
select b.b_id, b.b_code, b.b_name, a.*
from building b,
( select ma.b_id, ma.a_id, ma.addr1, ma.addr2, ma.addr3, m.c
from address ma,
( select maxa.b_id, max(maxa.a_id) a_id, count(*) c
from address maxa
group by maxa.b_id ) m
where ma.a_id = m.a_id ) a
where b.b_id = a.b_id (+);
Ключевые преимущества этого подхода:
- Доставляет любое количество адресных столбцов.
- Детерминистический, возвращает одинаковые результаты при каждом запуске.
- Не накладывает чрезмерных сложностей на ваш последний запрос, который, безусловно, будет более сложным, чем этот.
- Встроенное представление "A" может быть легко инкапсулировано в представление базы данных, возможно, назовите его представлением LATEST_ADDRESS:
create view latest_address (b_id, a_id, addr1, addr2, addr3, c) as
select ma.b_id, ma.a_id, ma.addr1, ma.addr2, ma.addr3, m.c
from address ma,
( select maxa.b_id, max(maxa.a_id) a_id, count(*) c
from address maxa
group by maxa.b_id ) m
where ma.a_id = m.a_id;
select b.b_id, b.b_code, b.b_name, a.*
from building b, latest_address a
where b.b_id = a.b_id (+);
Наслаждайтесь!
Matthew