ここから本文です

『DISTINCT』の代わりに『EXISTS』を用いる方法について。

int********さん

2015/1/1311:06:15

『DISTINCT』の代わりに『EXISTS』を用いる方法について。

理想形

SELECT DISTINCT ANO
FROM HOGEXX
WHERE SGCD = 'HOGEHOGE'

これらのサイトを参考にしましたが・・・
http://itpro.nikkeibp.co.jp/article/COLUMN/20060111/227105/
http://d.hatena.ne.jp/annin102/20060908/1157734624
上記サイトの用にEXISTSを用いて重複処理を行うことができませんでした。

こんな感じ?で試しましたが・・・。できませんでした。
SELECT ANO FROM HOGEXX
WHERE EXISTS (SELECT A.ANO FROM HOGEXX A,(SELECT ANO FROM HOGEXX WHERE SGCD = 'HOGEHOGE') B
WHERE A.ANO = B.ANO)

一つのテーブルのみでDISTINCTの代わりをEXISTSで補うことは可能なのでしょうか。
どなたかご教授下さい。
よろしくお願いします。

閲覧数:
30,154
回答数:
3
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

ent********さん

2015/1/1423:38:05

書くならこんな感じでしょう。

SELECT ANO FROM HOGEXX A
WHERE EXISTS (SELECT * FROM HOGEXX B WHERE A.ANO = B.ANO)
A.SGCD = 'HOGEHOGE'

ところで、なぜこんなノウハウが生まれてきたかというと、以前の Oracle は、DISTINCT や GROUP BY が使用されると、一部のケースを除いて、結果セットをソートすることで重複行を取り除いていました。

ソート処理は負荷が高い処理なので、EXISTS句に置き換えることでソート処理がなくなり高速化する可能性が高いという理屈です。

ただ、最近の Oracle は DISTINCT や GROUP BY に対して、基本的にソートすることなく重複行を取り除くようになっています。なので、無駄な結合を含む EXISTS 句を使用した文にするよりも、普通に DISTINCT の方が速いことが多いのではないかと思います。

ただし、etmagroさんが言われているように、いつも DISTINCT と EXISTS の文の結果が一緒になるわけではありません。結果が一緒にならないケースでは、目的に応じて使い分ける必要があります。

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

bun********さん

2015/1/1921:41:11

何のためにDISTINCTをEXISTS句にしたいのか、分かりませんが、
仮に、以下のようなテーブルだった場合、以下のSQLで抽出可能です。

○準備
create table HOGEXX
(
ID number(10)
, SGCD varchar2(10)
, ANO varchar2(10)
)
;

insert into HOGEXX values(1,'HOGEHOGE','a');
insert into HOGEXX values(2,'HOGEHOGE','a');
insert into HOGEXX values(3,'HOGEHOGE','b');
insert into HOGEXX values(4,'HOGEHOGE','c');
insert into HOGEXX values(5,'HOGEHOGE','d');
insert into HOGEXX values(6,'HOGEHOGE','d');
insert into HOGEXX values(7,'HOGEHOGE','d');
insert into HOGEXX values(8,'HOGEHOGE','d');
insert into HOGEXX values(9,'HOGEHOG3','x');

○SQL
SELECT DISTINCT ANO
FROM HOGEXX
WHERE SGCD = 'HOGEHOGE';
-- 実行結果:a/b/c/d

SELECT ANO
FROM HOGEXX T1
WHERE EXISTS(
SELECT 'X'
FROM HOGEXX T2
WHERE T2.ID = T1.ID
AND T2.ID = ( SELECT MIN( T3.ID ) FROM HOGEXX T3 WHERE T3.ANO = T1.ANO )
)
AND T1.SGCD = 'HOGEHOGE';
-- 実行結果:a/b/c/d


性能面は試してないので分かりませんが、
このケースはDISTINCTの方が↑かと。

jet********さん

2015/1/1400:09:10

『DISTINCT』の代わりに『EXISTS』を用いるなんて初耳で、何だろうと思ってリンク先を見てみましたが、なんのことはない、

「複数テーブルから情報を取得する際、内部結合だと、結合時のテーブル件数比によっては、抽出結果がだぶってしまうことがある。それを防ぐために、
・DISTINCTで重複を除外する
・内部結合をやめてEXISTSを用いた相関サブクエリを使用する
この2つの方法があり、後者の方が処理速度が速い(ことが多い)」

というだけの話でした。
要は、EXISTSを用いるテクニックは、複数テーブルから情報を取得したい…という限定されたシチュエーションでのみ有効なもので、そこから離れて「重複を削除したい」という一般的な目的には使えません。

DISTINCT と同様の働きをするのは、GROUP BY です。
これについては、下記の質問を参照してください。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1213964554...

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる