閲覧ありがとうございます.
現在SQLでデータベースの勉強をしているのですが,existsを用いて商演算を行おうとしてわからない箇所が出てきたので,その点に関しての質問をさせて頂きます.
例として,A,Bと名付けた2つのテーブルを最初に用意します.

[テーブル1(名前:机1)]
| 番号 |氏名|年齢| 好物 |
---------------------------
| 12 | あ | 1 | りんご |
| 23 | い | 1 | すいか |
| 23 | い | 1 | りんご |
| 45 | え | 3 | すいか |
| 45 | え | 3 | りんご |

[テーブル2(名前:机2)]
| 好物 |
----------
| りんご |
| すいか |

この机1を机2で割ることで,この要素を含む氏名を取り出したいと考えて,以下のようなSQL文を実行しました.

select 氏名 from 机1 A
where exists(
select * from 机2 B
where A.好物 = B.好物);

[求めている結果表示]
| 番号 |氏名|
-------------
| 23 | い |
| 45 | え |

[実際に表示された結果]
| 番号 |氏名|
-------------
| 12 | あ |
| 23 | い |
| 23 | い |
| 45 | え |
| 45 | え |

実行すると
(1)氏名が重複で表示されてしまう
(2)「りんご」のみ好物の「あ」も表示されてしまう
という問題が発生してしまい,色々と調べて考えたものの,結局分からなかったので,今に至ります.

長文・駄文すみませんでした.
まだSQLを学び初めて少ししか経っていないので,全く違うことをしていたらすみません.よろしければ,問題解決へのアドバイスをお願いします.

このQ&Aに関連する最新のQ&A

SQL 勉強」に関するQ&A: SQLの勉強がしたい

A 回答 (3件)

EXISTSを使って商演算を行っていく順序を書いておきます。



SELECT A.番号, A.氏名, A.年齢, A.好物,B.好物 FROM 机1 A,机2 B
とすることで、机1と机2の全ての組み合わせが出力されます。

| 番号 |氏名|年齢| 好物 |
---------------------------
| 12 | あ | 1 | りんご |
| 12 | あ | 1 |すいか |
| 23 | い | 1 | すいか |
| 23 | い | 1 | りんご |
| 45 | え | 3 | すいか |
| 45 | え | 3 | りんご |

上の表から机1に含まれないレコードを抽出します。


SELECT A.番号, A.氏名, A.年齢, A.好物,B.好物 FROM 机1 A,机2 B
WHERE NOT EXISTS (SELECT * FROM 机1 C WHERE A.番号=C.番号 AND A.氏名=C.氏名 AND A.年齢=C.年齢 AND B.好物=C.好物)

| 番号 |氏名|年齢| 好物 |
---------------------------
| 12 | あ | 1 |すいか |

最後に机1から、番号=12,氏名=あ,年齢=1 ではない番号、氏名を抽出します
データの重複を回避するため、DISTINCTを使用しています。(別に、GROUP BY でも構いません)

SELECT DISTINCT D.番号,D.氏名 FROM 机1 D
WHERE NOT EXISTS
(SELECT A.番号, A.氏名, A.年齢, A.好物,B.好物 FROM 机1 A,机2 B
WHERE NOT EXISTS (SELECT * FROM 机1 C WHERE A.番号=C.番号 AND A.氏名=C.氏名 AND B.好物=C.好物)
WHERE D.番号=A.番号,D.氏名=A.氏名,D.年齢=A.年齢)


上のSQLだと、少し冗長なのでまとめると、

SELECT DISTINCT A.番号,A.氏名 FROM 机1 A WHERE NOT EXISTS
(SELECT 1 FROM 机2 B WHERE NOT EXISTS(SELECT 1 FROM 机1 C
WHERE A.番号=C.番号 AND A.氏名=C.氏名 AND A.年齢=C.年齢 AND B.好物=C.好物))

となります。
    • good
    • 0
この回答へのお礼

こちらが恐縮してしまうほどの丁寧な回答,ありがとうございました.
おかげさまで.商演算において exists はどのような役割を持っているのか,ということについて自分なりに理解することができました.そして,質問の箇所に書いた問題点も,qbr2さんの回答を参考にして,無事に解決することができました.

本当にありがとうございました!

お礼日時:2009/05/27 18:22

人毎に、すべての好物を持つか探す必要があるので、今の正規化されていないテーブル構成では、テーブル1を、「人と好物」の関連付けのためと、最終的に「人を絞る」ための2回、参照する必要があります。



ここのカテゴリ通り、RDBMSはPostgreSQLですか?
バージョンは?

<SQL例1>not existsを2段階で使用
select *
from
(select
"番号","氏名"
from t1
group by "番号","氏名") as x
where not exists
(select 1 from t2 as y
where not exists
(select 1 from t1
where x."番号"="番号"
and y."好物"="好物"
)
)
;

<SQL例2>exceptを使用
select *
from
(select
"番号","氏名"
from t1
group by "番号","氏名") as x
where not exists
(select "好物" from t2
except
select "好物" from t1
where x."番号"="番号"
)
;
    • good
    • 0
この回答へのお礼

書き忘れてしまいすみませんでした.はい,このカテゴリを探したのもお察しの通り postgreSQL を使用しているからです.
あと,バージョンは 1.8.4 です
そして,回答ありがとうございました,先ほどchukenkenkouさんの回答を参考に実行してみたところ,自分が望む結果を得ることができました.
not existを2回実行することや except を使用するなどの方法は知らなかったので,この機会に勉強させて頂きました.
本当にありがとうございました.

お礼日時:2009/05/27 18:14

こんにちは


集合の商演算について、
うまく説明できないので、

多分この参考サイトに答えがのっているのではないでしょうか。

参考URL:http://oraclesqlpuzzle.hp.infoseek.co.jp/12-5.html
    • good
    • 0
この回答へのお礼

回答ありがとうございました.
こんなサイトがあったんですね,まだまだ調べ方が足りなかったようです.すみません.ありがたく参考にさせてもらいます.

お礼日時:2009/05/27 18:09

このQ&Aに関連する人気のQ&A

SQL 勉強」に関するQ&A: パースエラーとは?

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

QSQLの「句」とはなんですか

こんにちは。「文」や「式」や「句」の違いがよくわからなかったので、調べたら文と式はわかりました。

文はそれ単独で完結する言語要素

式はそれ単独では基本的に完結せず、文または式の一部として使用される言語要素です。
式の最大の特徴として、値を返すという点が挙げられます(文は値を返しません)。

定数式はその値そのものを返します。
条件式は真偽値(True/False)を返す式です。

ただ、「句」がどういったものかがわかりません。Order By句とか色々ありOrder Byが何を意味しているのか理解はできますが、「句」ということがばひっかかります。

ひらたくいうと、どういったことでしょうか?

Aベストアンサー

英語版Wikipediaに掲載されている図がこちら。
http://en.wikipedia.org/wiki/File:SQL_ANATOMY_wiki.svg
命令文(statement),節・句(clause),述部(predicate),式(experssion)という英単語が登場しています。

英語版Wikipediaに登場するClausesの説明文を日本語翻訳したのがこちら。
http://translate.google.co.jp/#en/ja/Clauses%2C%20which%20are%20constituent%20components%20of%20statements%20and%20queries.%20(In%20some%20cases%2C%20these%20are%20optional.)
[10] ANSI/ISO/IEC International Standard (IS). Database Language SQL—Part 2: Foundation (SQL/Foundation). 1999. に登場する記述とのこと。

英語版Wikipediaに掲載されている図がこちら。
http://en.wikipedia.org/wiki/File:SQL_ANATOMY_wiki.svg
命令文(statement),節・句(clause),述部(predicate),式(experssion)という英単語が登場しています。

英語版Wikipediaに登場するClausesの説明文を日本語翻訳したのがこちら。
http://translate.google.co.jp/#en/ja/Clauses%2C%20which%20are%20constituent%20components%20of%20statements%20and%20queries.%20(In%20some%20cases%2C%20these%20are%20optional.)
[10] ANSI/ISO/IEC International Stan...続きを読む


人気Q&Aランキング

おすすめ情報