![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
閲覧ありがとうございます.
現在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を学び初めて少ししか経っていないので,全く違うことをしていたらすみません.よろしければ,問題解決へのアドバイスをお願いします.
No.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.好物))
となります。
こちらが恐縮してしまうほどの丁寧な回答,ありがとうございました.
おかげさまで.商演算において exists はどのような役割を持っているのか,ということについて自分なりに理解することができました.そして,質問の箇所に書いた問題点も,qbr2さんの回答を参考にして,無事に解決することができました.
本当にありがとうございました!
No.2
- 回答日時:
人毎に、すべての好物を持つか探す必要があるので、今の正規化されていないテーブル構成では、テーブル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."番号"="番号"
)
;
書き忘れてしまいすみませんでした.はい,このカテゴリを探したのもお察しの通り postgreSQL を使用しているからです.
あと,バージョンは 1.8.4 です
そして,回答ありがとうございました,先ほどchukenkenkouさんの回答を参考に実行してみたところ,自分が望む結果を得ることができました.
not existを2回実行することや except を使用するなどの方法は知らなかったので,この機会に勉強させて頂きました.
本当にありがとうございました.
No.1
- 回答日時:
こんにちは
集合の商演算について、
うまく説明できないので、
多分この参考サイトに答えがのっているのではないでしょうか。
参考URL:http://oraclesqlpuzzle.hp.infoseek.co.jp/12-5.html
回答ありがとうございました.
こんなサイトがあったんですね,まだまだ調べ方が足りなかったようです.すみません.ありがたく参考にさせてもらいます.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Accessで別テーブルの値をフォ...
-
Recordset.FindFirstについて
-
Access 文字+年ごとの自動採番
-
最新の日付とその金額をクエリ...
-
access 自動採番 年が変わる...
-
[Access]異なるレコード間の文...
-
Accessで日付が変わると番号が...
-
アクセスで「空き番」の確認
-
GROUP BYを行った後に結合した...
-
Oracleでの文字列連結サイズの上限
-
select insertで複数テーブルか...
-
レコードが存在しなかった場合
-
Access終了時の最適化が失敗?
-
ACCESSの集計クエリで3件ある...
-
Excelで、改行がある場合の条件...
-
SELECTで1件のみ取得するには?
-
エクセルの指定したシートにエ...
-
GROUP BYを使ったSELECT文の総...
-
データセットのレコード更新が...
-
VB6.0のIsNull関数に相当するもの
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessで別テーブルの値をフォ...
-
最新の日付とその金額をクエリ...
-
access 自動採番 年が変わる...
-
Accessでのレコード存在チェック
-
[Access]異なるレコード間の文...
-
【アクセスVBA】テーブルにフィ...
-
Accessで日付が変わると番号が...
-
【Access】選択クエリのグルー...
-
アクセスで「空き番」の確認
-
【SQL】existsでの商演算
-
access 請求番号の自動採番
-
access 自動採番 「10-AA-000...
-
条件をつけて日付の古い行を抜...
-
Access 文字+年ごとの自動採番
-
Access:抽出して、色をつけたい。
-
Recordset.FindFirstについて
-
vba 直前の操作はキャンセルさ...
-
質問です。 下記のテーブルとデ...
-
Accessで自前の自動採番処理で...
-
ACCESSでの行番号の自動採番
おすすめ情報