エンジニアにとってみれば、SQL は使えてあたりまえかもしれませんが、営業や管理部の人からすれば魅惑の魔法といわれることもあります。 しかし非エンジニアの方でも SQL が使えた方がいいですし、 そのほうがエンジニアの作業も楽になります。
ここでは、 SQL による検索結果をひとつのテーブルとして扱う方法を説明します。 サブクエリと呼ばれるものです。
続きを読む 見るためのデータベース・SQL 検索結果をテーブルとして扱うエンジニアにとってみれば、SQL は使えてあたりまえかもしれませんが、営業や管理部の人からすれば魅惑の魔法といわれることもあります。 しかし非エンジニアの方でも SQL が使えた方がいいですし、 そのほうがエンジニアの作業も楽になります。
ここでは、 SQL による検索結果をひとつのテーブルとして扱う方法を説明します。 サブクエリと呼ばれるものです。
続きを読む 見るためのデータベース・SQL 検索結果をテーブルとして扱う今日もエラーが出ました。
ORA-01799: 列は副問合せに対して外部結合されません。
下のように解決しました。 (使っているデータベースは Oracle 10g か 11g のどっちかでした。)
エラーが出たのは次の結合条件。
1 2 3 4 |
LEFT JOIN JNYUKA FNY ON FNY.BUNNO = (SELECT MAX(SNY.BUNNO) FROM JNYUKA SNY WHERE SNY.BUNNO <= MAIN.BUNNO) |
LEFT JOIN
で結合するテーブルの結合条件に副問合せをつかうと駄目みたいです。
上のコードでやりたいのは、 JNYUKA.BUNNO
がメインテーブルの値(MAIN.BUNNO
)以下になっているもので、最大のものをとることです。下のように。
MAIN BUNNO | JNYUKA BUNNO | FNY BUNNO |
---|---|---|
1 | 1 | 1 |
2 | 2 | 2 |
3 | 2 |
上のコードではエラーがでます。 カーソルを使っていったんテーブルに入れるのも面倒です。そこで・・・
1 2 3 4 5 6 |
LEFT JOIN JNYUKA FNY ON FNY.BUNNO <= MAIN.BUNNO AND NOT EXISTS(SELECT 1 FROM JNYUKA SNY WHERE SNY.BUNNO > FNY.BUNNO AND SNY.BUNNO <= MAIN.BUNNO) |
このようにすればエラーはでません。 BUNNO
がメインテーブル以下のものをすべて結合した後で、最大のもののみに絞り込むイメージ。
別の例があったので・・・
Oracleで子テーブルの最新を外部結合できない!? で次のコードを見つけました。
1 2 3 4 5 6 7 8 9 |
select member.* from MEMBER member left outer join MEMBER_LOGIN memberLogin on member.MEMBER_ID = memberLogin.MEMBER_ID and memberLogin.LOGIN_DATETIME = (select max(MEMBER_LOGIN.LOGIN_DATETIME) from MEMBER_LOGIN where MEMBER_LOGIN.MEMBER_ID = member.MEMBER_ID) |
この場合だと
1 2 3 4 5 6 7 8 9 10 |
select member.* from MEMBER member left outer join MEMBER_LOGIN memberLogin on member.MEMBER_ID = memberLogin.MEMBER_ID and not exists(select MEMBER_LOGIN.MEMBER_LOGIN_DATATIME from MEMBER_LOGIN where MEMBER_LOGIN.MEMBER_ID = member.MEMBER_ID and memberLogin.LOGIN_DATATIME < MEMBER_LOGIN.LOGIN_DATATIME) |
とすればいいことになります。
ON
ではなくて JOIN
の中に条件を入れてしまう方法でも解決できます。