• ベストアンサー
  • 困ってます

distinct をexistsに変換する

distinctをexistsに変換した方がパフォーマンスが良いようで、 例えば以下の例があるとします ---------------------------------- (前)SELECT DISTINCT a.ID1, a.NAME1 FROM TABLE1 a, TABLE2 b WHERE a.ID1 = b.ID2 (後)SELECT a.ID1, a.NAME1 FROM TABLE1 a    WHERE EXISTS ( SELECT 'X' FROM TABLE2 b WHERE a.ID1 = b.ID2) ---------------------------------- もっと複雑なSQLの場合、EXISTSに変換できるのでしょうか?。複雑なSQLとは、 「複数のテーブルからカラムを取得」「テーブル結合が2つ以上」「外部結合」 などのSQLで、以下に例を示します。 (例)SELECT DISTINCT a.ID1,a.NAME1,b.ID2,b.NAME2,c.ID3,c.NAME3    FROM TABLE1 a,TABLE2 b,TABLE3 c    WHERE a.ID1 = b.ID1(+)      AND a.ID1 = c.ID1(+)

共感・応援の気持ちを伝えよう!

  • 回答数4
  • 閲覧数6153
  • ありがとう数2

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

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

効率的なSELECT文を書くコツは、 SELECT句に必要のないテーブルはFROM句に書かない、 です。 最初の例は、TABLE1はSELECT句にありますが、TABLE2は無いですよね? この場合、TABLE1のみのSELECT句・FROM句を書いて、 WHERE句にTABLE2を書いたほうが良いです。 WHERE句に別のテーブルを「引っ掛けたい」場合は、EXISTSやINを利用してください。 一般的にはEXISTSの方が早いです。 二番目の例は。そもそも、TABLE1,2,3がSELECT句にあるので「変換」は出来ませんし そもそも、EXISTSとDISTINCTは変換可能な関係性にありません。 ところで、この外部結合は古い(確かOracle方言?)書き方です。 SELECT DISTINCT a.ID1,a.NAME1,b.ID2,b.NAME2,c.ID3,c.NAME3    FROM TABLE1 a  LEFT OUTER JOIN TABLE2 b ON a.ID1 = b.ID1  LEFT OUTER JOIN TABLE3 c ON a.ID1 = c.ID1 がお勧めです。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

丁寧なご回答、どうもありがとうございました。 参考にいたします。 他の皆様もありがとうございました。

関連するQ&A

  • SQL文 テーブルの作成方法について

    以下のようなTABLE1からTABLE2というテーブルを作成したいと考えております。 元テーブル(TABLE1)は、IDという項目がキーとなってデータが入っており、NAME1とNAME2という項目があります。 (NAME1は必ず値が入っていますが、NAME2は値が入っていない場合もあります) 加工後のテーブル(TABLE2)で、NAME1とNAME2の値を結合した形で結果を出力したいと考えております。 (新たに作成したNAMEカラムは、必ずしもユニークになっているとは限りません。NAMEとIDを組み合わせるとユニークになります) ---------------------------------------------------- ■ TABLE1 ID NAME1 NAME1_CATE NAME2 NAME2_CATE ---------------------------------------------------- 001 鈴木 A 山田 B 002 山本 A 003 佐藤 A 高橋 B ---------------------------------------------------- ---------------------------------------------------- ■ TABLE2 ID NAME NAME_CATE ---------------------------------------------------- 001 鈴木 A 001 山田 B 002 山本 A 003 佐藤 A 003 高橋 B ・・・ ---------------------------------------------------- いろいろ試していますが、どのようなSQL文を書いたらよいのか分かりません。 現状のSQL(エラーとなります) ====================================================================================== SELECT ID, NAME, NAME_CATE FROM (SELECT ID, NAME1 as NAME, NAME1_CATE as NAME_CATE FROM TABLE1 WHERE NAME1<>NULL) JOIN (SELECT ID, NAME2 as NAME, NAME2_CATE as NAME_CATE FROM TABLE1 WHERE NAME2<>NULL) ====================================================================================== 初歩的な質問になるかと思ってしまうかと思いますが、よろしくお願いいたします。

  • DISTINCTの使い方を教えて下さい

    Select 文で DISTINCT を記述すると結果(Count)は-1となってしまいます。 DISTINCTを外すと全件表示されます。 これは何がまずいのでしょうか ? 環境 DB=SQLserver 2000 + IIS 5.0 + ASP 例:Select DISTINCT TABLE1,TABLE2,TABLE3 FROM TABLE ちなみにdbをAccess で使用している時とクエリアナライザではOKでした。

  • 2つのテーブルの結合に関してです

    お世話になります PHP5,MySql5.0.33にて開発を行っています 2つのテーブルの結合部分で困っています TABLE1 ---------------------------------- ID DATE1 DATE2  COUNT ---------------------------------- 1  2/27  2/20  10 2  2/27  2/20  10 ---------------------------------- TABLE2 ---------------------------------- ID DATE1 DATE2 COUNT ---------------------------------- 1  2/21  2/26  5 2  2/21  2/27  5 ---------------------------------- 上記2つのテーブル(TABLE1/TABLE2)から TABLE1のDATE1=2/27より過去の行とTABLE2のDATE2=2/27より過去の行を 取得したいのですが上手くいかず…(下SQLで記述しています) SELECT DISTINCT TABLE1.* FROM TABLE1,TABLE2 WHERE TABLE1.ID=TABLE2.ID AND TABLE1.ID=1 AND (TABLE1.DATE1<='2009/2/27' OR TABLE2.DATE2<='2009/2/27') (結合のそもそもの理解が間違っているかも知れませんが…;) 宜しくお願いします

    • ベストアンサー
    • MySQL

その他の回答 (3)

  • 回答No.4

## 余計なお世話ですけど。。。 (前)SELECT DISTINCT a.ID1, a.NAME1 FROM TABLE1 a, TABLE2 b WHERE a.ID1 = b.ID2 (後)SELECT a.ID1, a.NAME1 FROM TABLE1 a    WHERE EXISTS ( SELECT 'X' FROM TABLE2 b WHERE a.ID1 = b.ID2) のほうも、一緒の結果になるとは限りませんが。。。 例)TABLE2はTABLE1のID1がすべてID2にあるとして。 a.ID1, a.NAME1 1 あ 2 い 2 い 3 う というデータがあれば、 (前) 1 あ 2 い 3 う (後) 1 あ 2 い 2 い 3 う となりますが。 ・・・ID1が単独でプライマリキー、またはユニークインデックスとして設定されている という前提がないと同じ結果にはならないです。

共感・感謝の気持ちを伝えよう!

  • 回答No.3
  • entree
  • ベストアンサー率55% (405/735)

必ずしもできるとは限りません。少なくとも挙げられた例ではできません。 DISTINCTとEXISTSは別物です。 EXISTS句は(相関)副問合せなので、副問合せの外で列名を使用することができません。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ご回答ありがとうございます。 必ずしもできる訳ではないということですね。 了解しました。

  • 回答No.1

DISTINCTは重複の排除をする機能なので、EXISTSに変換はできません。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • Select Distinctについて

    SQL文の質問です。フィールドがTable1に100つあるとします。 select distinct XYZ From Table1という文があるとします。 これだとXYZのフィールドしか参照していないことになると思います。 そうではなくて、他の99フィールドの値も参照(データにアクセスしたい)したいと思っています。 select distinct XYZ, * From Table1とSelect * from Table1みたいなことをやりましたがエラーが発生しました。他の99フィールドを参照する方法はあるでしょうか?

  • SQL文について

    テーブルの結合について教えてください。 (DBはオラクルです) select * from table1,table2 where table1.カラム名=table2.カラム名; で、結合が出来ることは分かりました。 やりたいことはテーブルの結合と、ある期間のデータを持ってきたいのです。 select カラム名 from table1 where カラム名 between '20020213' and '20020218'; で期間を決めて引き出すやり方も分かっています。 一度に結合と期間を決めて引き出すやりかたってどうすればよいですか? それとも不可能ですか? 教えてください。

  • 差集合について

    MYSQL5.5について質問です。 Table1.idからTable2.idを引いて差集合を得たいとと思います。 例えば、 Table1.id 001 002 003 004 Tbale2.id 002 003 004 とあれば、最終的に欲しい結果は 001 のみです。 SQLを書くと下記のようなSQLになると思います。 mysql> SELECT table1.* FROM table1 -> LEFT JOIN table2 ON table1.id=table2.id -> WHERE table2.id IS NULL; しかし、これで差集合が得られるのかわかりません。 left joinして、table2 is nullにすれば、差集合に なるか教えて頂けますでしょうか? また、not existsで代用できるみたいですが、その場合、 どのようなSQLを書けばよいでしょうか?

  • SELECT文の二段重ね

    次のSQL文を実行します。 create table1 (id, english) insert table1 (1,"foo") insert table1 (2,"bar") create table2 (id, japanese) insert table2 (1, "ふー") insert table2 (2, "ばー") SQL文法としては誤ってますが、成功したとします。 いま、select id from table1 where english = 'foo'; で1が得られます。 いま、select japanese from table2 where id = 1; で"ふー"が得られます。 これを一つのSQLite3のselect文で実現できないでしょうか。 select japanese from table2 where id = (select id from table1 where english = 'foo'); で良いですか? カテゴリ選択にSQLiteが無いのは、人気が無いからですかね。

  • 重複レコードを高速で取得するSQL

    Access(mdb)から約2万件レコードのあるテーブルがあるとします。 列数は20ほど。 その中から、3つの列において重複しているレコードを取得したいのですが、 高速に取得する方法はありますでしょうか? (VB.NETで、重複レコードをユーザーに示す処理を作成したいのです) 以下のSQLを試したところ、1分以上時間がかかってしまいました。 ----------------------------- SELECT * FROM テーブルA table1 WHERE EXISTS ( SELECT * FROM テーブルA table2 WHERE table1.列A = table2.列A   table1.列B = table2.列B   table1.列C = table2.列C GROUP BY table2.列A HAVING COUNT(table2.列A) > 1 ) ----------------------------- アドバイスをお願いします。

  • phpmyadminのリレーション

    SELECT * FROM table1,table2 WHERE table1.id=table2.data_id; phpmyadminにて、上記のようなSQL文を実行してtable1とtable2のデータを リレーションにより表示します。 この時に表示した内容のテーブルを新規作成するにはどうすれば良いでしょうか?

    • ベストアンサー
    • MySQL
  • 別テーブルからSELECTした値を持つ行を削除するSQLは?

    削除 SQL がわかりません。 SQL-1 SELECT id FROM table2 WHERE date_in IS NULL; これで取得したidを持つレコード(別テーブル)を削除したいのですが、 どうすれば組み合わさるのでしょうか? DELETE FROM table1 WHERE id=???

  • PL/SQLのDELETE文について

    PL/SQLでDELETE文を書こうとしているのですが、 文法がわかりません。。。 分かる方がおられましたら、教えてくださいm(_ _)m 今、TABLE1を削除したいのですが、条件がいろいろあって、 以下のように書いてみたのですがダメでした。 こういう書き方は、できないんでしょうか・・・。 削除条件は、TABLE2に存在し、かつ、TABLE2のTENSUが0のもので、 TABLE3が存在しないものです。 DELETE TABLE1 FROM TABLE1 ,TABLE2 ,TABLE3 WHERE TABLE1.ID = TABLE2.ID AND TABLE2.TENSU = 0 AND Not Exists (SELECT TABLE3.ID FROM TABLE3 WHERE TABLE3.ID = TABLE2.ID) 説明が下手なので、うまく、伝わっているか、心配なのですが・・・、 よろしくお願いします。

  • UNION ALLしたテーブルを個別に並べ変え

    table1、table2、table3というテーブルがあり このそれぞれをidというカラムで並び替えたものを結合するので考えました。 SELECT * FROM `table1` UNION ALL SELECT * FROM `table2` UNION ALL SELECT * FROM `table3` ORDER BY `id` にすると全てを結合したものを並び替えるので SELECT *, '1' AS tbl FROM `table1` UNION ALL SELECT *, '2' AS tbl FROM `table2` UNION ALL SELECT *, '3' AS tbl FROM `table3` ORDER BY `tbl`,`id` という風に書いてみました、結果としてはよさそうですが 方法としては間違ってないでしょうか? 他にいい方法があればアドバイスをお願いします。

  • ACCSESSのクエリについて教えてください

    すみません! SQL初心者なのですがクエリについておしえてください。 table1 id kigou 1 a 2 b 3 c 4 d 5 e table2 id kigou 1 a 2 b 3 cc 4 ee 上記の2テーブルよりkigouのc d eが含まれるデータを抽出して kigouの1桁目が同じもののidを合計する場合、どのような 構文になりますでしょうか。。 以下のように記載しましたが、その後どうすればよいかわかりません。 select * from table1 left join table2 on table1.id=table2.id where table1.kigou in ('c','d','e') or table2.kigou in ('c','d','e') そもそもアプローチの仕方が間違っているのでしょうか。。