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

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

ただいまの
回答率

90.51%

  • MySQL

    7000questions

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

  • SQL

    3012questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 150

yayak

score 24

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

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

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

comments_table

comment_ID comment_content
1 hoge
2 fuga

comment_meta_table

meta_id comment_id meta_key meta_value
100 1 type type_A
101 1 userID 776
102 2 type type_A
103 2 userID 777

users_table

user_ID user_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でつなげると、途端に何も選択されない状態になってしまいます。

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

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

SELECT comments_table.comment_ID
FROM  comments_table 
      INNER JOIN comment_meta_table meta_type
      ON    comments_table.comment_ID=meta_type.comment_id 
        and meta_type.meta_key='type'
      INNER JOIN comment_meta_table meta_userid
      ON    comments_table.comment_ID=meta_userid.comment_id 
        and meta_userid.meta_key='userID'
      INNER JOIN users_table 
      ON meta_userid.meta_value=users_table.ID 
WHERE meta_type.meta_value='type_A'
  AND users_table.user_name='二郎'

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/05 18:48 編集

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

    キャンセル

  • 2019/03/05 21:11

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

    キャンセル

  • 2019/03/09 17:29

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

    キャンセル

+1

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

  • 元データ
create table comments_table(
comment_ID int primary key,
comment_content varchar(20));
insert into comments_table values
(1,'hoge'),
(2,'fuga'),
(3,'piyo'),
(4,'foo'),
(5,'bar');


create table comment_meta_table(
meta_id int primary key,
comment_id int,
meta_key varchar(20),
meta_value varchar(20));

insert into comment_meta_table values
(100,1,'type','type_A'),
(101,1,'userID','776'),
(102,2,'type','type_A'),
(103,2,'userID','777'),
(104,3,'type','type_A'),
(105,3,'userID','777'),
(106,4,'type','type_B'),
(107,4,'userID','777');

create table users_table(
user_ID varchar(20) primary key,
user_name varchar(20));
insert into users_table values
('776','一郎'),
('777','二郎');
  • 抽出
select comment_id from comment_meta_table as t2
where exists(
select 1 from comment_meta_table as t1
where exists(
select 1 from  users_table where user_name='二郎' 
and t1.meta_key='userID' 
and user_ID=t1.meta_value
)
and t2.comment_id=comment_id)
and meta_value='type_A'

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/05 18:36

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

    全体的な仕様をよく検討することをお勧めします。
    (テーブル構造は自分が決められないならしかたない)

    キャンセル

  • 2019/03/05 18:54 編集

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

    キャンセル

同じタグがついた質問を見る

  • MySQL

    7000questions

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

  • SQL

    3012questions

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