[Oracle]テーブルの最新の値を外部結合で取得したいなら。ORA-01799:列は副問い合わせに対して外部結合されません。

Oracleで発生したエラー

ORA-01799:列は副問い合わせに対して外部結合されません。

他にも解決策はあるのでしょうが、今回はこれで解決

Oracleでは外部結合で最大値を取得できなかった

状況
簡単に例にして見ましたが事象はこちら。

・商品マスタの中でその商品の予約者も管理している。
・予約者がいた時だけ予約者の名前を取得したい。
・顧客情報マスタは登録情報が更新されるたびに、レコードを新規に作成し、暦管理している。
・予約者の名前は最新の登録名で取得したい。
・退会していると現在歴はなくなるので、sysdateでは取得できない。

テーブル構成はこんな感じに。

商品マスタ:product

論理名 物理名
商品コード product_code
商品名 product_name
発売日 release_date
予約者コード client_code

顧客情報マスタ:client

論理名 物理名
顧客コード client_code
顧客名 client_name
有効開始日 start_date
有効終了日 end_date

商品の過去の予約内容を確認する際に、退会してしまった顧客でも最後に登録されていた氏名を取得します。
最後の氏名としているのは名前の登録が変更された場合のことを考慮してのこと。

予約者がいないことも考えられるので、顧客マスタは外部結合にしたい。
顧客マスタからはMAX関数を使って予約者の最新のレコードを取得したいのですが、
外部結合を使用するとダメなようでした。

ORA-01799:列は副問い合わせに対して外部結合されません。

このエラーが出るので対策としては
下記のように外部結合部分を変更したこと。

—–ダメな例—–
SELECT
pro.release_date 発売日
pro.product_name 商品名,
cli1.client_name 予約者名
FROM
product pro,
client cli1
WHERE
pro.release_date = to_date(‘20190401′,’YYYYMMDD’)
AND cli1.start_date(+) = (
SELECT
MAX(cli2.START_DATE)
FROM
client cli2
WHERE
pro.client_code = cli2.client_code(+)
)

—————
—–良い例—–
SELECT
pro.release_date 発売日
pro.product_name 商品名,
cli1.client_name 予約者名
FROM
product pro,
client cli1
WHERE
pro.release_date = to_date(‘20190401′,’YYYYMMDD’)
AND pro.client_code is null
OR (pro.client_code is not null
cli1.start_date = (
SELECT
MAX(cli2.START_DATE)
FROM
client cli2
WHERE
pro.client_code = cli2.client_code
)

この方法が最適かと言われれば自信はありませんが、ひとまず解決したのでよしとします。