from...whereをfrom...join..onにする方法

このQ&Aのポイント
  • あるSQL文のfrom...where句をfrom...join...on句に書き直したい場合、fetch first 1 row onlyが難しいポイントですが、パフォーマンスの問題を考慮しつつ解決法を見つけていきましょう。
  • from...where句で書かれたSQL文をfrom...join...on句に書き換えるには、fetch first 1 row onlyの扱いが難しいですが、適切な解決方法を見つけることで問題を解消できます。
  • SQL文のfrom...where句をfrom...join...on句に変換する場合、fetch first 1 row onlyの存在が難点ですが、パフォーマンスを損なわずに解決策を見つけましょう。
回答を見る
  • ベストアンサー

from...where を from...join..on にするには

以下のSQL文は from ... where ... で書かれていますが これを from ... join ... on ... で書き直したいのですが可能でしょうか? select X.col1, U.col1 from TABLE_X as X ,TABLE_U as U where U.REC_NO = (select B.REC_NO from TABLE_A as A, TABLE_B as B where A.ITME = B.ITEM and X.DATA = A.DATA fetch first 1 row only ) むずかしくしているのは、fetch first 1 row only なのですが これがないと where句のかっこのなかのselect文は複数の結果を返します しかし、その複数の結果はすべて同じものになることがデータ上保証されています 。 fetch first を除いて select distinct としても同じ結果となりますが パフォーマンスがひどく低下してしまいます。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

on句は結合条件でfetch firstは抽出条件なのでwhere句をon句にする単純な書き直 しはできないと思います。やるとしたら副選択のselect文をfrom句に書いて一時テーブルとしてfetch firstをdistinctにするしかないような気がします select X.col1, U.col1 from (select distinct B.REC_NO from TABLE_A as A, TABLE_B as B where A.ITME = B.ITEM and X.DATA = A.DATA) as Z inner join TABLE_X as X on ... inner join TABLE_U as U on ... fetch first にくらべて distinct なので遅いような気がしますが 実際には副選択がないためにそための内部的に作られる一時表が軽くなるのでこちらのほうが速いと思います。

nekosogi
質問者

お礼

このとおりに試したら数倍速くなりました。 びっくりです。 一時表の作られ方を考えないといけないですね。 ありがとうございました。

その他の回答 (1)

回答No.1

IBMのDB2のSQLですか? 書き直す理由は? →書き直す方法があっても、特定のRDBMSの独自機能を含んでいたら意味がないのですよね? >fetch first を除いて select distinct としても >同じ結果となりますがパフォーマンスがひどく低下 1対nになるのは、どの表、どの条件式ですか? インデクスを定義しても、実用に耐えない状況ですか?

nekosogi
質問者

お礼

DB2のSQLです。 研究あるいは挑戦です(笑)。 できないならしょうがないのであきらめます。

関連するQ&A

  • inner joinとwhereでの結合の違いは?

    お世話になります。 たとえば、テーブルが複数(この場合2つ)ある場合。 (1) test(カラム:table_id,table_name) (2) tester(カラム:table_id,table_name) 以下のクエリは条件的に select a.table_id, a.table_name from test a inner join tester b on a.table_id = b.table_id ************* select a.table_id, a.table_name from test a , tester b where a.table_id = b.table_id 同じですよね? パフォーマンス的にもjoinすることのメリットが判りません。

  • WHERE句はJOIN結合前結合後どちらに効くのか

    以下の2つのSQLを比較してどちらがパフォーマンスが良いでしょうか。 先に抽出して結合した方が良いと昔聞いた事がありましたが 記憶があいまいになってしまいました。 (1) SELECT * FROM A JOIN B ON A.*** = B.*** WHERE A.*** = '0001' (2) SELECT * FROM (SELECT * FROM A WHERE A.*** = '0001') AS A JOIN B ON A.*** = B.***

  • JOINの時のONとWHEREの違いについて

    二つのテーブルをjoinして比較したいときに 比較対象の項目がA,Bとあったとします。AはキーですがBはキーではありません。 このとき、ON句でTABLE1.A=TABLE2.A and TABLE1.B=TABLE2.B とかくのと ON句でTABLE1.A=TABLE2.A WHERE TABLE1.B=TABLE2.B と書くのとで結果に違いはあるのでしょうか? 違いが見つけられずに困っています。 違っていない場合、どちらが一般的でしょうか? どうぞよろしくお願い致します。

  • oracleでwith句の結果を使ってupdate

    oracleでwith句の結果を使って外部結合?でupdateしたいのですが 上手くいきません。 oracleでは無理なのでしょうか。 よろしくお願いいたします、。 /*---------- with v1 as ( select row_number() over(PARTITION BY ・・・ ORDER BY ・・・) as rnum ,no ,col1 ,・・・ from ・・・ ) update ( select A.col1 A_COL, v1.col2 B_COL from table1 A inner join table2 B on A.cd1=B.cd1 inner join v1 on A.no=v1.no where v1.rnum=1 and ・・・ ) set A_COL=B_COL ; ----------*/ と書いたのですが、 実際に実行してみると、 カッコ「(」、「)」がないとか、 selectが必要とか, A_COLやB_COLが無効ですとか、 となります。 どこが悪いのでしょうか。 oracleではupdateでwithは使えないのでしょうか。 よろしくお願いします。

  • joinの場合のテーブル名の別名の使用方法

    select * from table1 a,table2 b where a.field1=b.field1; とできますが select * from table1 as a left join table2 as b on a.field1=b.field1; とできません。 joinの場合にテーブル名の別名を使う方法を教えてください

  • SQLServer T-SQL テーブルのJOIN

    こんにちは。 テーブル"TABLE_A"、"TABLE_B"があり、 各々のテーブルにカラム"COL"があります。 カラム"COL"にインデックスを作成しています。 テーブル"TABLE_A"、"TABLE_B"をカラム"COL"で結合 する際の演算子にLIKE文を用いています。"TABLE_B"の カラム"COL"に"%"を付加していますが、これが原因で "COL"のインデックスが効きません。どのようにすれば LIKE検索でインデックスを有効にすることができるの でしょうか? SELECT * FROM TABLE_A INNER JOIN TABLE_B ON TABLE_A.COL LIKE TABLE_B.COL+'%'

  • PostgreSQLでサブクエリーをJOINする方法

    たとえば、 select A.field1, B.field1 from (select field1 from table1 where field2='x') A, (select field1 from table2 where filed2='y') B where A.field2=B.field2; のようなことをしたいのですが、 Oracleだとこの方法でデータを取ってこれるのですが、PostgreSQLだとエラーで返ってきてしまいます。 PostgreSQLのバージョンは6.5.3です。 バージョンが上がると上記の書き方も通るようになるのでしょうか? また、上記の書き方と同じ意味を持つ他の書き方をご存知でしたら教えてください。よろしくお願いします。

  • WHERE文の中で除算

    SQLのWHERE文の中で計算をしているのですが、「除数が0です」とのエラーがでてしまいます。 同じ計算をSELECT文の中にいれると、エラーにならず、計算結果がでるのですが、どうしてでしょうか? SELECT DATA, (A + B - C) / (A + B) * 100 FROM table ↑この時は計算結果がでます。 SELECT DATA FROM table WHERE (A + B - C) / (A + B) * 100 <= 50.0 ↑「除数が0です」といわれてしまいます。

  • カウントして抽出するsqlをまとめたい

    mysql初心者です。宜しくお願い致します。 PHP+Mysqlで以下のスクリプトを組んでいます。 変数aを一旦決めておき、カウント結果次第で変数aの値を広げるというものです。 これをSQL文一発にまとめたいのですが、可能でしょうか? mysqlのバージョンは5.1.34です。お詳しい方、ご教授お願い致します。 $a = 10; //仮に10 $query = "SELECT COUNT(*) AS cnt FROM mydb WHERE col_a BETWEEN ( 100 - $a ) AND ( 100 + $a ) AND col_b BETWEEN ( 100 - $a ) AND ( 100 + $a )"; $result = mysql_query($query); $row = mysql_fetch_array($result); if($row[cnt] < 10){$a = 20;} //件数が10件以下ならaの範囲を広げて結果取得 $query = "SELECT * FROM mydb WHERE col_a BETWEEN ( 100 - $a ) AND ( 100 + $a ) AND col_b BETWEEN ( 100 - $a ) AND ( 100 + $a )"; $result = mysql_query($query);

    • ベストアンサー
    • MySQL
  • こういう場合のSQLの書き方。

    はまっています。お知恵を貸してください。 Oracle8i WindowsNT4.0です。 tbl_testというテーブルがあります。 データが以下のように入っています。 col1   col2   col3 --------------------------------- A     B     C      A B     A     A C この時、col1 col2 col3それぞれのカラムの中で、 Aという値が何個あるか数えたいのです。 今は以下のように三つにわけてセレクトしていますが、 これをひとつの式にまとめたいのですが、可能でしょうか? UNIONしても欲しい答えは返ってきません。 =========================== SELECT COUNT(col1) AS col1 FROM tbl_test WHERE col1 = 'A' =========================== SELECT COUNT(col2) AS col2 FROM tbl_test WHERE col2 = 'A' =========================== SELECT COUNT(col3) AS col3 FROM tbl_test WHERE col3 = 'A' 欲しい答えは、 col1   col2   col3 ----------------------- 1     2     1 です。 なお、家に検証環境が無いので、検証&お礼は明日のお昼くらいになると思います。 宜しくお願い致します。