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

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

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

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

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

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

PHP

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

Q&A

解決済

4回答

597閲覧

登録されているデータにより紐づいているテーブルが変わる物のデータの取得方法が分からない。

sayochika

総合スコア3

MySQL

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

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

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

PHP

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

0グッド

0クリップ

投稿2024/09/20 06:18

実現したいこと

teamsテーブル
| id | title | ……
| 1 | 巨人 |
| 2 | 阪神 |

usersテーブル
| id | name | age | title |……
| 1 | tanaka | 25 | ピッチャー |
| 2 | nakata | 30 | キャッチャー |

hobbby_skillsテーブル
| id | type | skill_id | hobby_id |……
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 |

hobbiesテーブル
| id | type | title |……
| 1 | 1 | 早い  |
| 2 | 2 | 正確  |
| 3 | 3 | 丁寧  | 
| 4 | 4 |ピンチヒッター|

(※ここに登場するデータは仮情報なので本当のデータではありません)

分かりにくかったら申し訳ございません。
上記のテーブルで、hobby_skillsテーブルやhobbiesテーブルのtypeの値が1か3の場合、skill_idはteamsテーブルのidと紐づき、typeの値が2か4の場合、skill_idはusersテーブルのidと紐づいています。
hobby_skillsテーブルのhobby_idがhobbiesテーブルのidと紐づいています。
ここで、usersテーブルのデータをSELECT文で表示していく時に、それぞれ対応したtypeの値のtitleを同時に表示させたいです。
例えば、nakata, 30, キャッチャー, 正確……という感じで。
説明が難しいのですが、よろしくお願いいたします。

発生している問題・分からないこと

https://waterfalls.hatenablog.com/entry/2020/05/30/013149

このサイトを参考に実施してみたのですが、私の場合間に違うテーブルがあるのでうまく表示できません。

該当のソースコード

特になし

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

SELECT name,
hobbies.title AS facilities
FROM users
LEFT JOIN hobby_skills ON hobby_skills.skill_id = users.id AND hobby_skills.hobby_id = hobbies.id AND hobby_skills.type = 2, 4

全然違うと思うのですが、もうわからなさ過ぎて嫌になってきました。

補足

特になし

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

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

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

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

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

guest

回答4

0

できないことはないと思いますが管理も煩雑ですし効率も悪いので、typeでこねくりまわさずに普通にテーブルをわけて正規化した方がよいでしょう。

参考

users,teams,hobbiesの独立したテーブルがあり
users=teams、users=hobbiesをリレーションさせるために中間テーブルを作るというのではればこんな感じ

SQL

1create table teams(tid int primary key ,title varchar(20)); 2insert into teams values(1,'giants'),(2,'tigers'); 3 4create table users(uid int primary key ,name varchar(20),age int,title varchar(20)); 5insert into users values 6(1,'tanaka',25,'pitcher'), 7(2,'nakata',30,'catcher'); 8 9create table hobbies(hid int primary key,title varchar(20)); 10insert into hobbies values 11(1,'fast'), 12(2,'correct'), 13(3,'carefully'), 14(4,'pinch hitter'); 15 16create table user_team(uid int not null,tid int not null,primary key(uid,tid) ); 17insert into user_team values(1,1),(2,2); 18 19create table user_hobby(uid int not null,hid int not null,primary key(uid,hid) ); 20insert into user_hobby values(1,1),(2,2); 21 22 23select * from users as t1 24left join user_team as t2 on t1.uid=t2.uid 25left join teams as t3 on t2.tid=t3.tid 26left join user_hobby as t4 on t1.uid=t4.uid 27left join hobbies as t5 on t4.hid=t5.hid

投稿2024/09/20 06:38

編集2024/09/20 08:39
yambejp

総合スコア116629

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

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

sayochika

2024/09/20 07:21

ご回答ありがとうございます。 その場合どのようにすればよいのでしょうか。 SQLはあまりわからなくて…。 調べてはいるのですが、理解が追いつきません。
yambejp

2024/09/20 07:55

そもそもskill_idがなんなのか謎です なにがどうリレーションしているか明確にしてください
guest

0

自己解決

(SELECT GROUP_CONCAT(title) FROM hobbies WHERE id IN (SELECT hobby_id FROM hobby_skills WHERE hobby_id = hobbies.id AND skill_id = users.id AND type = 2 OR type = 4)) AS hobby,

としたらできました。

投稿2024/09/20 10:00

sayochika

総合スコア3

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

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

yambejp

2024/09/20 10:25

くりかえしで申し訳ないですが「できないことはない」レベルのことはやらない方がいいです
tezcello

2024/09/20 12:48

> ~ AS hobby, としているので、SELECT句の一部だと推測します。 __だって、提示された中には users というテーブルは無いので __これの外側にあるのだろうと で SELECT users.*, (SELECT GROUP_CONCAT(title) FROM hobbies WHERE id IN ( SELECT hobby_id FROM hobby_skills WHERE hobby_id = hobbies.id AND skill_id = users.id AND type = 2 OR type = 4 ) ) AS hobby FROM users; という SQLを投げてみると id name age title hobby 1 tanaka 25 ピッチャー ピンチヒッター 2 nakata 30 キャッチャー 正確,ピンチヒッター という結果が得られます。 これが欲しかった結果でしょうか? 質問文からは推測が出来ませんでした。 > typeの値が2か4の場合 この条件と AND type=2 OR type=4 とがマッチしないのでは? 多分 AND (type=2 OR type=4) の勘違い? __だから「ピンチヒッター」が出てきてしまう > hobby_skillsテーブル(略)のtypeの値が1か3の場合、skill_idはteamsテーブルのidと紐づき > typeの値が2か4の場合、skill_idはusersテーブルのidと紐づいています > それぞれ対応したtypeの値のtitleを同時に表示させたい hobby_skills.type が 1 or 3 の時は hobby_skills.skill_id は teams.id から引っ張ってきた teams.title が使われるはずでしょうが、チーム名(巨人、阪神)は「できました」で得られるデータには存在しない様です。 __当方の推測した SQL が間違っている可能性はあります tanaka と関連付くのは、hobby_skills.skill_id が users.id を指していて、それが 1 である場合です。 hobby_skills.skill_id が 1 であるレコード(hobby_skills.id=1) がは存在しますが、hobby_skills.type が 1 であるので、hobbies.id を指していますから、このレコードが usersテーブルと関連付く事は無いはずです。 __少なくても提示されているデータの範囲内では これらより、質問された内容は、解決していないはずです。 または、質問文の内容が求めているモノと合致していないと思います。 本番の(「質問用の」ではなく「本来の」)テーブル等に対する際に、本当に求めているモノであるかを十分にご確認ください。 __リレーション関係をもう一度見直して、テーブル構造を再検討する必要がありそうです
guest

0

SQL

1SELECT U.*,T.*,H.* 2FROM hobby_skills AS S 3 LEFT JOIN teams AS T ON S.skill_id=T.id 4 LEFT JOIN hobbies AS H ON S.hobby_id=H.id 5 LEFT JOIN users AS U ON S.skill_id=U.id;

とりあえず、こんなSQL(↑)で結果を取得するとこんな感じ(↓)
__カラム名の重複は無視しました

idnameagetitleidtitleidtypetitle
1tanaka25ピッチャー1巨人11早い
2nakata30キャッチャー2阪神22正確
NULLNULLNULLNULLNULLNULL33丁寧
NULLNULLNULLNULLNULLNULL44ピンチヒッター

例えば、nakata, 30, キャッチャー, 正確……という感じで。

この目標だけなら達成できていますが、何が本当にやりたいのかを質問文から読み取れませんでした。
hobby_skills.typeの違いによってtitleとして取得したい値が hobbies.title であるか、teams.title であるのかが切り替えたいのなら

SQL

1SELECT U.*, 2 CASE 3 WHEN S.type IN (1,3) THEN T.title 4 WHEN S.type IN (2,4) THEN H.title 5 ELSE NULL 6 END title 7FROM hobby_skills AS S 8LEFT JOIN teams AS T ON S.skill_id=T.id 9LEFT JOIN hobbies AS H ON S.hobby_id=H.id 10LEFT JOIN users AS U ON S.skill_id=U.id;

の様に SELECT句を書き換えれば、こんな感じに取得できます。

idnameagetitletitle
1tanaka25ピッチャー巨人
2nakata30キャッチャー正確
NULLNULLNULLNULLNULL
NULLNULLNULLNULLピンチヒッター

__カラム名が重複するけれど、何が適切なのか判らないのでそのままにした

説明が難しい

やりたい事を丁寧に説明してもらえないと、回答者は何ともならないです...
テーブル名もカラム名も内容も、全て質問用のテキトーなモノでしょうが、もう少し理解し易いモノを選んで頂けると嬉しいです。

hobby_skillsテーブルやhobbiesテーブルのtypeの値が

hobby_skills.type は先述の様に使いましたが、hobbies.type の使い道が解りませんでした。

usersテーブルのデータをSELECT文で表示していく時に、それぞれ対応したtypeの値のtitleを同時に表示させたい

提示されたデータが悪いのか、当方の理解が悪いのか...
巨人に所属するuserを取得しようとしても、tanakaさんは得られないけれど、それが仕様に合っているのかは不明...

投稿2024/09/20 09:10

tezcello

総合スコア326

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

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

0

Joinする対象のテーブルに関してunionでteamsとusersを重ねたテーブルを作って、1,3と2,4を持たせるとか1,3は1で2,4は2に変換する分岐とか、まあそんな感じでやれば行けるとは思いますが、ベストかどうかは分かりません。
もしかしたらシンプルにjoinだけでできるのかもしれないですが、頭の中だけだとどんな列になるのか想像がつきません。テーブルが別なので無理な気もしますが(nullなら変換するとかをSELECTなどの参照の方で書けば行けるとは思うが)

Unionはサブクエリにて行う想定です。

今回の場合どうなるか
SQLはデータをレコードでしか取れないので、どういうレコードが欲しいのか?を先ず考えて、データの形式(列)で表せるか考えます。パターンが違い物理的に表現不可能なら取得できないデータということになります。

この場合、もとのIDという列とtitleという列が必要そうですよね。
また、1,2の分岐用の仮想的な列も必要そうです。

Joinする時にどのような行が必要かをonで指定します。

まずはjoinする前のデータをテーブル形式で抽出して見ると良いかと思います

投稿2024/09/20 07:28

編集2024/09/20 09:52
utm.

総合スコア320

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

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

sayochika

2024/09/20 07:38

unionについて調べてみましたが今回の場合だとどうなるのでしょうか。 もう頭が働きません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問