🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

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

Q&A

解決済

2回答

1205閲覧

mySQLで2つのテーブルのあるカラムが一致したレコードを抽出したいのですが、うまくいきません。

KojiUchida

総合スコア5

MySQL

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

0グッド

0クリップ

投稿2019/10/28 10:45

編集2019/10/28 10:53

前提・実現したいこと

mySQLで2つのテーブルのあるカラムが一致したレコードを抽出したいのですが、うまくいきません。

テーブルAには主キーのvidに複数のkeyとvalueがあり、 テーブルBにはcidに複数のkeyとvalueがあります。(正規化がうまくできていませんが、この構造を前提にプログラムの質問をさせてください。)
テーブルBのkeyとvalueに合致するA.vidを抽出することが目的です。
下記のテーブルの状態であれば、vid=1002が抽出できればよいのですが、うまくできていません。
初心者につき、ご教授いただければ幸いです。よろしくお願いいたします。

[テーブルA]
vid key value
1001 1 aaa
1001 2 bbb
1001 3 ccc
1002 1 ddd
1002 2 eee
1002 3 fff
1003 1 ggg
1003 2 hhh
1003 3 iii
;

[テーブルB]
cid key value
2001 1 ddd
2001 2 eee
2001 3 fff
;

該当のソースコード

SELECT vid FROM A WHERE
((value=(SELECT value FROM B WHERE key=1)) AND key=1)) AND
((value=(SELECT value FROM B WHERE key=2)) AND key=2)) AND
((value=(SELECT value FROM B WHERE key=3)) AND key=3));

試したこと

WHERE節のAND条件をバラして個別に実行すると、vid=1002が出力されますので、AND条件の考え方が誤解しているように思います。

SELECT vid FROM A WHERE
((value=(SELECT value FROM B WHERE key=1)) AND key=1));

SELECT vid FROM A WHERE
((value=(SELECT value FROM B WHERE key=2)) AND key=2));

SELECT vid FROM A WHERE
((value=(SELECT value FROM B WHERE key=3)) AND key=3));

よろしくお願いいたします。

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

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

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

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

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

Orlofsky

2019/10/28 11:18

教授 → 教示
guest

回答2

0

ベストアンサー

縦を横に変換して結合してみる。
変換部分は**group_concat()**で変換できるような内容ならもう少し簡潔になるかもです。
[MySQL]GROUP_CONCATで縦のデータをカンマ区切りで取得

SQL

1select vid 2from ( 3 select vid 4 , max(key1_value) as key1_value 5 , max(key2_value) as key2_value 6 , max(key3_value) as key3_value 7 from ( 8 select vid 9 , case when key=1 then value end as Key1_value 10 , case when key=2 then value end as Key2_value 11 , case when key=3 then value end as Key3_value 12 from A 13 ) a_closs 14 group by vid 15 ) a_value inner join ( 16 select max(key1_value) as key1_value 17 , max(key2_value) as key2_value 18 , max(key3_value) as key3_value 19 from ( 20 select case when key=1 then value end as Key1_value 21 , case when key=2 then value end as Key2_value 22 , case when key=3 then value end as Key3_value 23 from B 24 ) b_closs 25 ) b_value 26 on a_value.key1_value=b_value.key1_value 27 and a_value.key2_value=b_value.key2_value 28 and a_value.key3_value=b_value.key3_value

投稿2019/10/28 12:20

sazi

総合スコア25327

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

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

sazi

2019/10/28 12:27 編集

Bが1セットならBの整形はmaxでのグルーピングを使用せずにサブクエリーの方が高速な気がします。
KojiUchida

2019/10/28 13:53

sazi様 ご確認ありがとうございます。 なるほど!! 横に変換することは考えていませんでしたが、その方法もありですね。 maxでもサブクエリでも実現できましたので、ベストアンサーとさせていただきます。ありがとうございました。
guest

0

SQL

1SELECT A.vid FROM A 2INNER JOIN B 3ON A.key = B.key ;

SQL入門レベルの勉強はきちんとやらないと仕事になりませんよ。

投稿2019/10/28 10:58

Orlofsky

総合スコア16417

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

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

KojiUchida

2019/10/28 13:18

ご回答ありがとうございます。正確には、 SELECT A.vid FROM A INNER JOIN B ON A.key = B.key AND A.value = B.value ; ですね。 そもそも、質問の事例が適切ではなく、これでは聞きたいことが伝わらないので、本件はCloseとし、別で質問とさせていただきます。 ※valueは数値で、key=1は等しい、key=2は以上、key=3は以下としたく、その場合、個別でWHERE節でANDを取らざるとえないとしていたため、JOINは避けていました。質問内容が適切でなく、申し訳ありませんでした。
Orlofsky

2019/10/28 13:58

「質問への追記・修正」に修正依頼を書きましたが、 ここの掲示板は質問も回答も修正できるのはご存知で?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問