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

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回答

580閲覧

【SQL】複数のテーブルを条件付きで結合したい

babybaby

総合スコア40

MySQL

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

SQL

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

0グッド

0クリップ

投稿2022/11/02 06:38

編集2022/11/02 09:49

前提

MySQL 5.7

ユーザが気に入ったコミックを投票するシステムがあり、以下のテーブル構造を持っています。
イメージ説明

ユーザの属性は一般ユーザと管理ユーザの2種類あり、usersのadmin(1が入っていれば管理者)カラムで管理しています。

実現したいこと

雑誌と、その雑誌が持つコミックの内、最も管理者ユーザに投票されたコミック1件を結合させて取得するSQLを教えていただきたいです。

結合するイメージとしては以下です。
結合したいテーブルに色を付けています。
イメージ説明
雑誌A - コミックA:コミックAが最も管理者ユーザからの投票が多いため
雑誌B - コミックC:コミックCが最も管理者ユーザからの投票が多いため
雑誌C - なし:管理者ユーザの投票がないため、取得しない

サンプル

SQL

1-- Create 2CREATE TABLE users ( 3 id integer, 4 name varchar(100), 5 admin integer 6); 7 8CREATE TABLE votes ( 9 id integer, 10 comic_id integer, 11 user_id integer 12); 13 14CREATE TABLE comics ( 15 id integer, 16 magazine_id integer, 17 name varchar(100) 18); 19 20CREATE TABLE magazines ( 21 id integer, 22 name varchar(100) 23); 24 25-- Insert 26-- ユーザ 27insert into users(id, name, admin) values(1, "一般ユーザA", 0); 28insert into users(id, name, admin) values(2, "管理者ユーザA", 1); 29 30-- 雑誌 31insert into magazines(id, name) values(1, "雑誌A"); 32insert into magazines(id, name) values(2, "雑誌B"); 33insert into magazines(id, name) values(3, "雑誌C"); 34 35-- コミック 36insert into comics(id, magazine_id, name) values(1, 1, "コミックA"); 37insert into comics(id, magazine_id, name) values(2, 1, "コミックB"); 38insert into comics(id, magazine_id, name) values(3, 2, "コミックC"); 39insert into comics(id, magazine_id, name) values(4, 3, "コミックD"); 40 41-- 投票 42insert into votes(id, comic_id, user_id) values(1, 1, 1); 43insert into votes(id, comic_id, user_id) values(2, 1, 2); 44insert into votes(id, comic_id, user_id) values(3, 1, 2); 45insert into votes(id, comic_id, user_id) values(4, 2, 1); 46insert into votes(id, comic_id, user_id) values(5, 2, 1); 47insert into votes(id, comic_id, user_id) values(6, 2, 1); 48insert into votes(id, comic_id, user_id) values(7, 3, 1); 49insert into votes(id, comic_id, user_id) values(8, 3, 2); 50insert into votes(id, comic_id, user_id) values(9, 4, 1);

補足

  • 管理者ユーザが投票したコミックが存在しなれば、その雑誌は取得しない

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

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

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

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

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

yambejp

2022/11/04 13:21

votesのid=2とid=3が同じ(comic_id=1/ user_id=2)なんですが大丈夫ですか? これは同じ人間が同じコミックを何度も投票できるということですので、 不正投票の温床になります。 かりに上記が良かったとしてcomic_id=1と2の投票数が同じ3票ですが これはどちらが優先されるのでしょうか?(両方受け取りたい?) 、
babybaby

2022/11/04 14:48

> 同じ人間が同じコミックを何度も投票 どこかでガードしなければなりませんが、本筋とずれるので一旦許容するとさせてください。 > comic_id=1と2の投票数が同じ3票ですがこれはどちらが優先 最も管理者ユーザ(userのadminが1)に投票されたコミックを抽出したいので、comic_id=1を優先でお願いします。
guest

回答2

0

ベストアンサー

先ほどwindow関数を使ったSQLにて誤って回答してしまいました。
以下あらためて、再度訂正して回答します。

select m.name,b.comic_name from magazines m
inner join
(
select distinct a.comic_name,a.magazine_id from (
select w.comic_name,w.magazine_id,w.id,w.user_name,count(*) from
(
select
c.name as comic_name
,c.magazine_id
,v.user_id as kind
,u.id
,u.name as user_name
,u.admin as admin
from comics c
inner join votes v on c.id = v.comic_id
inner join users u on v.user_id = u.id
) w where w.admin = 1
group by w.comic_name,w.magazine_id,w.id,w.user_name
) a
) b
on m.id = b.magazine_id
;

+---------+---------------+
| name | comic_name |
+---------+---------------+
| 雑誌A | コミックA |
| 雑誌B | コミックC |
+---------+---------------+
2 rows in set (0.00 sec)

mysql>

投稿2022/12/01 14:29

編集2022/12/01 16:17
sooni

総合スコア51

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

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

0

「雑誌と、その雑誌が持つコミックの内、最も管理者ユーザに投票されたコミック1件を結合させて取得する」の意味がわからないのですが、voteのcomic_idでgroup by してcountすれば投票が多いコミックはわかります

追記

複数のコミックのうち、最も投票数の多いコミックと雑誌を結合させ

SQL

1select comic_id,count(*) as cnt from votes group by comic_id order by cnt desc limit 1

で最大の投票されたcomi_idは拾えますが
comicsテーブルにcomic_idが含まれてないので集計のしようがないですね

投稿2022/11/02 06:56

編集2022/11/02 07:24
yambejp

総合スコア114769

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

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

babybaby

2022/11/02 07:15

雑誌は複数のコミックを持っており、その複数のコミックのうち、最も投票数の多いコミックと雑誌を結合させたい。という意味でした。 もしよろしければ実際のSQLもご教授頂けませんでしょうか?
yambejp

2022/11/02 07:26

テーブルが中途半端なのでいまの情報からでは集計は困難です。 ER図ではなく具体的なリレーションがわかるようなサンプルを提示されたほうがよいとおもいます
babybaby

2022/11/02 07:47

サンプルを追加しました。 > comicsテーブルにcomic_idが含まれてないので集計のしようがない 失礼しました。ER図には明記していませんが、すべてのテーブルでユニークな「id」カラムを持ちます。
yambejp

2022/11/02 07:49

であれば、提示したクエリをサブクエリにして、comicsテーブルにjoin、さらにそれをmagazinesテーブルにjoinすればよいでしょう
babybaby

2022/11/02 08:00

ご提示下さったサブクエリの場合、limit 1を指定しているためグループ化されたコミックの中から1件しか取得されないのではないでしょうか? サンプルでいうと、雑誌AとコミックAの結合のみになると思います。雑誌BとコミックCも同時に結合して取得するような記述が望ましいです。
yambejp

2022/11/02 09:18

雑誌ごとに最大投票数のコミックを抽出したいということですかね・・・ sampleは図ではなくcreate table+insertで示してもらうと回答がぶれづらいです
babybaby

2022/11/02 09:50

> 雑誌ごとに最大投票数のコミックを抽出 わかりにくくて申し訳ないです、そういうことです。 サンプルを追加しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問