- PR -

SQL Server で Oracle の MINUS 集合演算子と同等の SQL 文

投稿者投稿内容
うきょきょ
常連さん
会議室デビュー日: 2004/01/09
投稿数: 44
投稿日時: 2004-08-30 15:31
SQL Server 2000で OracleのMINUS集合演算子と同等のSQL文が
知りたく、FAQだろうなとも思ったのですが、MSDNには使えない
(http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vdbt7/html/dvconquerydesignerconsiderationssqlserver.asp)
としか書かれて無く、UsersGroupの過去ログに同じ質問があったのですが
回答の方が文字化けしているようで参照できません。

お教え願えないでしょうか?
[UsersGroup問題]
http://www.users.gr.jp/ml/archive/viewer.aspx?name=sql&no=8603
[UsersGroup回答]
http://www.users.gr.jp/ml/archive/viewer.aspx?name=sql&no=8604
[UsersGroup結果]
http://www.users.gr.jp/ml/archive/viewer.aspx?name=sql&no=8606
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-08-30 15:55
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vdbt7/html/dvconquerydesignerconsiderationssqlserver.asp
このページの情報は、「使えない」とは書いてないですよ?

引用:

サポートされていないクエリ、または部分的にサポートされているクエリ

SQL Server クエリの種類によっては、クエリ デザイナでグラフィカル表示できないものがあります。そのようなクエリでも、SQL ペインに入力して正しく実行できます。ただし、クエリを実行したとき、またはペインを変更したときに、クエリ デザイナで [クエリの定義が異なります] ダイアログ ボックスが表示され、エラーが報告されます。


 デザイナで、グラフィカル表示できないけれど、正しく実行できます、と書いてありますよ?
うきょきょ
常連さん
会議室デビュー日: 2004/01/09
投稿数: 44
投稿日時: 2004-08-30 16:10
レスありがとうございます。

SQLクエリーアナライザーで、以下を試したのですがminus部分は
(無効な構文などの)エラーにこそなりませんが、無視されているように
見受けられます。

---Create Table
create Table TestA( Field char(1) )
create Table TestB( Field char(1) )

---Insert
Insert Into TestA(Field)Values('1')
Insert Into TestA(Field)Values('2')
Insert Into TestB(Field)Values('1')
Insert Into TestB(Field)Values('3')

---Select
Select * From TestA
minus
Select * From TestB

---結果
Field
-----
1
2

(2 件処理されました)

Field
-----
1
3

(2 件処理されました)
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-08-30 16:54
NOT EXISTSを使う、って書いてありますね。

[UsersGroup結果]
http://www.users.gr.jp/ml/archive/viewer.aspx?name=sql&no=8606
うきょきょ
常連さん
会議室デビュー日: 2004/01/09
投稿数: 44
投稿日時: 2004-08-30 17:43
レスありがとうございます。

select * from TestA where not exists
(select * from TestB where TestA.Field = TestB.Field)

で確かに出来ました!!
not existsってこういう事だったんですね--;

ありがとうございました。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-08-30 20:04
はにまるです。
引用:

うきょきょさんの書き込み (2004-08-30 17:43) より:
select * from TestA where not exists
(select * from TestB where TestA.Field = TestB.Field)


Oracleでは、副問合にて主問合せの項目を利用する文法は、
パフォーマンス劣化原因として嫌われています。
名称は忘れましたが、、、
様は、TestAのレコード件数分 TestBのSelect文を発行する形式になる為、
TestAの件数×TestBの件数が検索対象となるからです。
ただ、Oracleでの話なのでご注意を。

回避策としては、
Exist の場合は、単純結合
Not Exist の場合は、TestA に対し TestBを外部結合して、
TestAの情報とTestBの必須項目を取得します。
その結果を副問合せとして、TestBの必須項目が Nullのものを取得します。
これまた、Oracleでの話なのでご注意を。


#追記(アップする程でもないので)
 未記入さんフォローありがとうございます。


[ メッセージ編集済み 編集者: はにまる 編集日時 2004-08-31 09:45 ]
未記入
大ベテラン
会議室デビュー日: 2003/11/24
投稿数: 121
投稿日時: 2004-08-30 23:13
引用:

副問合にて主問合せの項目を利用する文法は、
パフォーマンス劣化原因として嫌われています。
名称は忘れましたが、、、


相関サブクエリ、ね。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2004-08-31 11:28
引用:

はにまるさんの書き込み (2004-08-30 20:04) より:
Oracleでは、副問合にて主問合せの項目を利用する文法は、
パフォーマンス劣化原因として嫌われています。
名称は忘れましたが、、、
様は、TestAのレコード件数分 TestBのSelect文を発行する形式になる為、
TestAの件数×TestBの件数が検索対象となるからです。
ただ、Oracleでの話なのでご注意を。



ちょっと誤解が。
TestAは丸々スキャンされるわけじゃなく、他の抽出条件があれば、それに当てはまるもののみがスキャン対象になります。
TestBのほうは結合列にインデックスがあれば、当然それが使われます。で、普通はインデックスがあります。

サブクエリがパフォーマンス劣化の原因になるかどうかは状況次第で、それほど嫌われているわけではありません。

引用:

回避策としては、
Exist の場合は、単純結合



これはDISTINCTを使わないと等価にならない場合があるので要注意。

スキルアップ/キャリアアップ(JOB@IT)