質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

4945閲覧

MySQL で2つの結果を比較して片方に含まれないデータを抽出したい(not existsを利用しました)

hidepon

総合スコア206

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/06/03 07:42

編集2017/06/03 08:20

次のような2つのSQLと結果があります・

SQL1 select d.no as no from tbl_d as d inner join tbl_e as e on e.no = d.no where e.auth1 = '0' and e.auth1 <> '1';

この結果が

結果1 | no | | 001 | | 003 | | 007 | | 008 | | 010 | | 011 | | 012 | | 015 | | 016 | | 020 | | 025 | | 030 | | 035 | | 045 | | 050 | | 060 | | 065 | | 070 | | 080 | | 085 | | 090 | | 095 | | 096 | | 105 | | 106 | | 107 | | 110 | | 112 | | 115 | | 121 | | 125 | | 130 | | 135 | | 136 | | 140 | | 142 | | 145 | | 150 | | 160 | | 165 | +-----+ 40 rows in set (0.00 sec)

そして2つ目のSQL

select a.no as no from tbl_a as a inner join tbl_b as b on a.j_num = b.j_num inner join tbl_c as c on a.no = c.no where c.no <> '141' and b.j_num = '5432456782';

この結果が

+-----+ | eno | +-----+ | 012 | | 130 | +-----+

とします。
結果1-結果2を得ようと次のSQLを組みましたがうまく結果が得られません。

select a.no as no from tbl_a as a inner join tbl_b as b on a.j_num = b.j_num inner join tbl_c as c on a.no = c.no where c.no <> '141' and b.j_num = '5432456782' and not exists( select * from tbl_d as d inner join tbl_e as e on e.no = d.no where e.auth1 = '0' and e.auth1 <> '1');
希望する結果 | no | | 001 | | 003 | | 007 | | 008 | | 010 | | 011 | | 015 | | 016 | | 020 | | 025 | | 030 | | 035 | | 045 | | 050 | | 060 | | 065 | | 070 | | 080 | | 085 | | 090 | | 095 | | 096 | | 105 | | 106 | | 107 | | 110 | | 112 | | 115 | | 121 | | 125 | | 135 | | 136 | | 140 | | 142 | | 145 | | 150 | | 160 | | 165 | +-----+

(追記)希望する結果を記述しました。

とするとempty となってしまいます。
どこがおかしいのか分からず困っています。
ご助言、ご指導いただければと思います。
宜しくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hihijiji

2017/06/03 07:58

2つ目のSQLの結果の '012', '130' は一つ目のSQLの結果に含まれてますが?
hidepon

2017/06/03 08:04 編集

この場合ってEMPTY になるのが正解なのでしょうか?この時の対処法ってPHP側でするのでしょうか?よくわかっていなくて困っています。SQLで解決できる方法があれば教えてください
hihijiji

2017/06/03 08:10

2つ目のSQLの結果のなかで、1つ目のSQLに含まれないものが欲しいのですね?でしたらそのように書いてあります。
hidepon

2017/06/03 08:13

やりたいこととしては結果の引き算をしたいんです。not in のほうがいいんでしょうか?
hihijiji

2017/06/03 08:17

質問欄に希望する出力結果を書いてください。
hidepon

2017/06/03 08:28

希望する結果を追記しました。宜しくお願いいたします。
guest

回答2

0

not exists を使う場合は、相関サブクエリにする必用があります。
サブクエリのWhere句にメインの主キーと関連付ける条件を追加する。
そうしないと、サブクエリのレコードは常に存在するので、not exists は常にFalse、よって結果はemptyです。

下記などを参照してサブクエリの抽出条件を考えてみてください。

【 SQL 備忘録 】相関サブクエリ ~ 理解に挫折したとき & 忘れたときに 訪れると すごくわかりやすい入門者向け 解説ウェブサイトへのインデックス - Qiita

ただ、相関サブクエリは複雑になるし、重いので、今回の要件には適していないと思います。

Not In を使うとシンプルに記述できるが、重いらしい。

両者を Left Join で結合して、2つ目のSQLのキーフィールドがNullでないものを抽出するという方法もあります。こちらの方が軽いかも知れません。インデックスの設定にもよると思いますので、実際に試してみて、決めてください。

単純化したモデルでのSQL例を提示しておきますので、参考にして実際のSQLを記述してください。

tbl_a (id)
tbl_b (id)
tbl_a から tbl_b の id を除いたものを抽出。

相関サブクエリ

SQL

1select a.id 2from tbl_a as a 3not exists( 4 select * from tbl_b as b 5 where a.id = b.id 6 );

not in 使用

SQL

1select id 2from tbl_a 3id not in ( 4 select id from tbl_b 5 );

left join 使用

SQL

1select a.id 2from 3 tbl_a as a 4 left join 5 tbl_b as b 6 on a.id = b.id 7where 8 b.id is null;

投稿2017/06/03 09:11

編集2017/06/03 09:31
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

書かれたSQLの頭とexistsの中が反対になっているだけです。

環境が無いので未チェックですがだいたいこんな感じで

SQL

1SELECT d.no 2FROM tbl_d AS d 3INNER JOIN tbl_e AS e 4ON e.no = d.no 5WHERE e.auth1 = '0' AND e.auth1 <> '1' 6 AND NOT EXISTS 7( 8 SELECT 1 9 FROM tbl_a as a 10 INNER JOIN tbl_b as b 11 ON a.j_num = b.j_num 12 INNER JOIN tbl_c as c 13 ON a.no = c.no 14 WHERE c.no <> '141' 15 AND b.j_num = '5432456782' 16 AND a.no = d.no 17 LIMIT 1 18)

投稿2017/06/03 08:28

編集2017/06/03 08:58
hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hidepon

2017/06/03 08:35

ご返答有難うございます。逆にしても同じ結果になります・・・orz
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問