閲覧ありがとうございます.
現在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で質問しましょう!
似たような質問が見つかりました
- Oracle 質問です。 下記のテーブルとデータがあり、 取得想定結果のように出力したいです。 下記のsqlだと0 2 2023/05/23 19:10
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- PHP PHP MySql ページング 2 2022/09/20 06:38
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- Oracle 下記のsqlで取得されるレコード以外を取得する方法ありますでしょうか。 SELECT B.番号, B 2 2022/04/20 23:21
- Oracle sqlで質問です。 Aテーブルの登録番号をキーにBテーブルから確認番号を取得したいのですが、Bテーブ 4 2023/05/18 13:08
- PostgreSQL postgreSQL カラムの全ての値を取得したい 3 2022/10/07 12:33
- MySQL 下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「名前(first name) 1 2023/06/24 13:03
- PHP Q&Aサイトを作成していてURLの生成方法について迷っているのでアドバイスお願い致します 1 2023/08/10 16:42
- MySQL 複数DBテーブルからのデータ取得 3 2022/05/17 15:02
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「黒歴史」教えて下さい
- ・2024年においていきたいもの
- ・我が家のお雑煮スタイル、教えて下さい
- ・店員も客も斜め上を行くデパートの福袋
- ・食べられるかと思ったけど…ダメでした
- ・【大喜利】【投稿~12/28】こんなおせち料理は嫌だ
- ・前回の年越しの瞬間、何してた?
- ・【お題】マッチョ習字
- ・モテ期を経験した方いらっしゃいますか?
- ・一番最初にネットにつないだのはいつ?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Accessで別テーブルの値をフォ...
-
最新の日付とその金額をクエリ...
-
ACCESSでVBAを用いて自動的に番...
-
Access 文字+年ごとの自動採番
-
ACCESSでの行番号の自動採番
-
access 請求番号の自動採番
-
Accessでのレコード存在チェック
-
access 自動採番 「10-AA-000...
-
条件をつけて日付の古い行を抜...
-
【アクセスVBA】テーブルにフィ...
-
access 自動採番 年が変わる...
-
Oracleでの文字列連結サイズの上限
-
GROUP BYを行った後に結合した...
-
SELECTで1件のみ取得するには?
-
Excelで、改行がある場合の条件...
-
Access終了時の最適化が失敗?
-
select句副問い合わせ 値の個...
-
レコードが存在しなかった場合
-
カレントレコードが無い事を判...
-
実績累計の求め方と意味を教え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessで別テーブルの値をフォ...
-
最新の日付とその金額をクエリ...
-
Accessで日付が変わると番号が...
-
access 自動採番 年が変わる...
-
Accessでのレコード存在チェック
-
【アクセスVBA】テーブルにフィ...
-
条件をつけて日付の古い行を抜...
-
access 自動採番 「10-AA-000...
-
vba 直前の操作はキャンセルさ...
-
アクセスで「空き番」の確認
-
Access:抽出して、色をつけたい。
-
[Access]異なるレコード間の文...
-
Access 文字+年ごとの自動採番
-
質問です。 下記のテーブルとデ...
-
【Access】選択クエリのグルー...
-
Recordset.FindFirstについて
-
access 請求番号の自動採番
-
Accessで自前の自動採番処理で...
-
〜のような結果を出すためのSQL...
-
ACCESSでの行番号の自動採番
おすすめ情報