SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Oracle SQLアンチパターンの問題集

OracleのSQLのアンチパターンの問題集2

from句のテーブル数を減らす

ダウンロード SourceCode (1.1 KB)

修正後のSQLと解説

exists述語を使用

修正後のSQL1(exists述語を使用)
select Val1,Val2
  from moto a
 where exists(select 1 from saki b
               where b.Val1 = a.Val1
                 and b.Val2 = a.Val2)
order by Val1,Val2;

 sakiテーブルに存在することが出力条件であることに注目してexists述語を使い、大本のselect文のfrom句にあるテーブルを2個から1個に減らすことができました。大本のselect文のfrom句にあるテーブルが1個になったので、表別名による列修飾を行ってる箇所を減らすことができました。

in述語を使用

修正後のSQL2(in述語を使用)
select Val1,Val2
  from moto
 where (Val1,Val2) in(select Val1,Val2
                        from saki)
order by Val1,Val2;

 別解として、マルチカラムin述語を使用したのが上記のSQLです。

 exists述語では、相関なサブクエリを使っていましたが、in述語では、非相関なサブクエリを使ってますので、in述語の中のselect Val1,Val2 from sakiを単独で実行可能です。

 解析しやすさも可読性の一部だと考えれば、SQLを解析する際にSQLの一部をコピーしてそのまま実行可能なin述語は、exists述語よりも可読性が高いかもしれません。

 さらに、列名はスコープの狭い方が優先されますので、表別名による列修飾が完全に不要になりました。

intersect集合演算を使用

修正後のSQL3(intersect集合演算を使用)
select Val1,Val2 from moto
intersect
select Val1,Val2 from saki
order by Val1,Val2;

 select句の全ての列で存在確認を行っていることに注目して、intersect集合演算を使用してもよいです。これが最も可読性が高いSQLだと思います。

 intersectではなくintersect allを使うと、重複行を消すという目的がないことを明示できるのですが、Oracle 11g R2ではintersect allが実装されていないのでintersectを使ってます。

 上記のSQLのイメージは下記です。intersect集合演算に対応するベン図と黄緑線をイメージしてます。

SQLのイメージ
SQLのイメージ

次のページ
3. 自テーブルを参照するSQLのアンチパターン

この記事は参考になりましたか?

Oracle SQLアンチパターンの問題集連載記事一覧
この記事の著者

山岸 賢治(ヤマギシ ケンジ)

趣味が競技プログラミングなWebエンジニアで、OracleSQLパズルの運営者。AtCoderの最高レーティングは1204(水色)。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3231 2010/08/20 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー