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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

2197閲覧

SQLで3つのテーブルを結合してWHEREで検索する方法につきまして

yayak

総合スコア66

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2019/03/05 08:53

編集2019/03/05 08:56

SQLを急きょ勉強しているのですが、本当にまだまだ不出来で、悩んでおります。

テーブルを3つ組み合わせて、特定のデータを取得しようとして、期待通りの結果が出ません。

以下の3つのテーブルがあったとします。

comments_table

comment_IDcomment_content
1hoge
2fuga

comment_meta_table

meta_idcomment_idmeta_keymeta_value
1001typetype_A
1011userID776
1022typetype_A
1032userID777

users_table

user_IDuser_name
776一郎
777二郎

「comment_meta_table」の「type」が「typeA」かつ、
「users_table」の「user_name」が「二郎」の、
「comments_table」の「comment_ID」を取得しよう思い、以下のように書きました。

SELECT DISTINCT comments_table.comment_ID FROM $comments_table INNER JOIN $comment_meta_table ON $comments_table.comment_ID = $comment_meta_table.comment_id INNER JOIN $users_table ON $comment_meta_table.meta_value = $users_table.ID WHERE ( comment_meta_table.meta_key = 'type' AND comment_meta_table.meta_value = 'type_A' ) AND users_table.user_nicename = '二郎')

上記の文の、WHERE以降の条件を、ANDでつなげずに、
WHERE comment_meta_table.meta_key = 'type' AND comment_meta_table.meta_value = 'type_A'
とするか、
WHERE users_table.user_nicename = '二郎'
とすると、片方の条件だけでの検索は実現するのですが、2つの条件をANDでつなげると、途端に何も選択されない状態になってしまいます。

上記のコードを見て、おかしな点がお分かりになる方がいらっしゃいましたら、どうかご教授頂けましたら幸いです。

どうか、どうか宜しくお願い致します。

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

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

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

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

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

guest

回答2

0

データの持ち方が相当わるいですが、変更できないのかもしれないのでそのまま行きます
また、サンプル数が少なくて検証がしづらいので勝手に足しておきます

  • 元データ

SQL

1create table comments_table( 2comment_ID int primary key, 3comment_content varchar(20)); 4insert into comments_table values 5(1,'hoge'), 6(2,'fuga'), 7(3,'piyo'), 8(4,'foo'), 9(5,'bar'); 10 11 12create table comment_meta_table( 13meta_id int primary key, 14comment_id int, 15meta_key varchar(20), 16meta_value varchar(20)); 17 18insert into comment_meta_table values 19(100,1,'type','type_A'), 20(101,1,'userID','776'), 21(102,2,'type','type_A'), 22(103,2,'userID','777'), 23(104,3,'type','type_A'), 24(105,3,'userID','777'), 25(106,4,'type','type_B'), 26(107,4,'userID','777'); 27 28create table users_table( 29user_ID varchar(20) primary key, 30user_name varchar(20)); 31insert into users_table values 32('776','一郎'), 33('777','二郎');
  • 抽出

SQL

1select comment_id from comment_meta_table as t2 2where exists( 3select 1 from comment_meta_table as t1 4where exists( 5select 1 from users_table where user_name='二郎' 6and t1.meta_key='userID' 7and user_ID=t1.meta_value 8) 9and t2.comment_id=comment_id) 10and meta_value='type_A'

投稿2019/03/05 09:24

yambejp

総合スコア114784

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

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

yambejp

2019/03/05 09:36

ご提示のメタデータ形式は拡張性はよいのですが、 データ型の指定ができないし、状況を選ばないと正規化方法としては 非効率的ですね 不特定の回答をとるアンケート(例えばあなたの趣味は?とか)のようなものだと 良いと思いますが、userIDやtypeなどcommentに1対1でぶら下がる作りなら 正規化しないほうがよいです。 (もちろんコメントidに対してuserIDやtypeが複数もてるとかだと話しは代わってきます) 全体的な仕様をよく検討することをお勧めします。 (テーブル構造は自分が決められないならしかたない)
yayak

2019/03/05 09:54 編集

yambejp様、知らなかったことにたくさん気付かせてくださり、心より感謝申し上げます。 コードがまだ自分には調べないとわからないこともあり、ただただ尊敬の念を抱いております。 しっかり、勉強させて頂きます。 そして、確かに、ものすごく効率の悪いテーブル構造だなと改めて思い、今夜、データベースの構造を変える決意をしました。yambejp様、本当に、有難うございます。
guest

0

ベストアンサー

comment_meta_tablemeta_keyが'TYPE'と'userID'のぞれぞれと結合しないと駄目ですね。
comment_meta_tablemeta_key毎のテーブルとして考えてください。

SQL

1SELECT comments_table.comment_ID 2FROM comments_table 3 INNER JOIN comment_meta_table meta_type 4 ON comments_table.comment_ID=meta_type.comment_id 5 and meta_type.meta_key='type' 6 INNER JOIN comment_meta_table meta_userid 7 ON comments_table.comment_ID=meta_userid.comment_id 8 and meta_userid.meta_key='userID' 9 INNER JOIN users_table 10 ON meta_userid.meta_value=users_table.ID 11WHERE meta_type.meta_value='type_A' 12 AND users_table.user_name='二郎'

投稿2019/03/05 09:05

編集2019/03/05 09:19
sazi

総合スコア25174

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

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

yayak

2019/03/05 09:49 編集

回答を拝見させて頂いた時、おおげさではなく、目頭が熱くなりました。 僕の書いた、「肉を切ることもなく焼くこともなくちぎって食べる」原始人のようなコードに対し、 sazi様の書いたコードはとてもわかりやすく、優しく、SQLがわからなすぎて折れかかっていたのですが、とても温かみを感じました。 もっともっと精進します。 本当に、有難うございます。
sazi

2019/03/05 12:11

少し照れました。 そして、低下してた回答する事に対するモチベが上がりました。
yayak

2019/03/09 08:29

ただただ、尊敬致します。 有難うございました<(_ _)>!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問