メリトン、
このアプローチでは、ネストされたインラインビューを使用します。私はこのアプローチを大規模なデータセットで証明しましたが、非常にうまく機能します。
クエリを理解する最良の方法は、最も内側の「M」インラインビューから開始することです。デバッグと明確さのためにカウントを追加しました。これにより、各建物の最大(つまり最新の???)アドレスIDが識別されます。
select maxa.b_id, max(maxa.a_id) a_id, count(*) c
from address maxa
group by maxa.b_id;
次の「A」インラインビューは、上記の「M」インラインビューを使用して取得するアドレスを決定し、そのアドレスIDに結合して、一連のアドレスフィールドを返します。
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 (+);
楽しみ!
マシュー