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

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

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

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

SQL

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

Q&A

解決済

1回答

1295閲覧

MySQLのテーブルからある列ごとにランダムな行を返すSQLを作りたい

taro_nii_chan

総合スコア207

MySQL

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

SQL

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

0グッド

0クリップ

投稿2018/11/10 23:19

環境

  • macOS High Sierra バージョン 10.13.6
  • mysql Ver 14.14 Distrib 5.6.38, for osx10.9 (x86_64) using EditLine wrapper

やりたい事

次のようなテーブルがあります。

SQL

1mysql> SELECT * FROM style; 2+----+----------+----------+------------+------------------+ 3| id | salon_id | genre_id | genre | image_url | 4+----+----------+----------+------------+------------------+ 5| 1 | 1 | 1 | short | style_000000.jpg | 6| 7 | 1 | 1 | others | style_000001.jpg | 7| 8 | 2 | 1 | short | style_000002.jpg | 8| 9 | 1 | 4 | medium | style_000004.jpg | 9| 10 | 2 | 4 | others | style_000005.jpg | 10| 11 | 3 | 4 | medium | style_000003.jpg | 11| 12 | 2 | 5 | long | style_000013.jpg | 12| 13 | 4 | 5 | very_short | style_000017.jpg | 13| 14 | 5 | 3 | medium | style_000014.jpg | 14| 15 | 5 | 4 | others | style_000019.jpg | 15| 16 | 1 | 4 | long | style_000015.jpg | 16+----+----------+----------+------------+------------------+ 1711 rows in set (0.00 sec)

genre_idgenreは1:1に対応しています。
ここから各genre(もしくはgenre_id)毎にランダムな1行を返すSQLを作りたいです。

やった事

  • まずgenreを一意に取って来たいのでその部分の確認をしました。

SQL

1mysql> SELECT genre FROM style GROUP BY genre; 2+------------+ 3| genre | 4+------------+ 5| long | 6| medium | 7| others | 8| short | 9| very_short | 10+------------+ 115 rows in set (0.00 sec)
  • 次に、genreshortであるものの中からランダムに1行を取り出すSQLをも確認しました。

SQL

1mysql> SELECT * FROM style WHERE genre = 'medium' ORDER BY rand() LIMIT 1; 2+----+----------+----------+--------+------------------+ 3| id | salon_id | genre_id | genre | image_url | 4+----+----------+----------+--------+------------------+ 5| 14 | 5 | 3 | medium | style_000014.jpg | 6+----+----------+----------+--------+------------------+ 71 row in set (0.00 sec) 8 9mysql> SELECT * FROM style WHERE genre = 'medium' ORDER BY rand() LIMIT 1; 10+----+----------+----------+--------+------------------+ 11| id | salon_id | genre_id | genre | image_url | 12+----+----------+----------+--------+------------------+ 13| 11 | 3 | 3 | medium | style_000003.jpg | 14+----+----------+----------+--------+------------------+ 151 row in set (0.00 sec) 16 17mysql> SELECT * FROM style WHERE genre = 'medium' ORDER BY rand() LIMIT 1; 18+----+----------+----------+--------+------------------+ 19| id | salon_id | genre_id | genre | image_url | 20+----+----------+----------+--------+------------------+ 21| 9 | 1 | 3 | medium | style_000004.jpg | 22+----+----------+----------+--------+------------------+ 231 row in set (0.01 sec) 24 25mysql>

分からないこと

恐らくこれらを組み合わせればgenre毎にランダムな1行を返すSQLが出来るのかなと思うのですが、その先が分かりません。ググった範囲では「subquery」、「left join」、「inner join」辺りがキーになるのかなとは思うのですが、ここで立ち止まってしまっています。

具体的なSQLを教えていただきたいのと、これは出来ればなのですが考え方も教えていただけるとありがたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

genre_idとgenreは1:1に対応しています。

そもそもそうなってませんよね?
例えば・・・

  • id=1、genre_id=1:genre=shortに対して
  • id=7、genre_id=1:genre=other

同様に

  • id=7、genre_id=1:genre=other
  • id=10、genre_id=4:genre=other

つまりこれはn対nの対応です
その関係はこの際無視してgenre_id毎にランダムに1行ずつ拾うならこう

SQL

1create table tbl( 2id int primary key, 3salon_id int, 4genre_id int, 5genre varchar(10), 6image_url varchar(30), 7index(id ,genre_id) 8); 9 10insert into tbl values 11(1,1,1,'short','style_000000.jpg'), 12(7,1,1,'others','style_000001.jpg'), 13(8,2,1,'short','style_000002.jpg'), 14(9,1,4,'medium','style_000004.jpg'), 15(10,2,4,'others','style_000005.jpg'), 16(11,3,4,'medium','style_000003.jpg'), 17(12,2,5,'long','style_000013.jpg'), 18(13,4,5,'very_short','style_000017.jpg'), 19(14,5,3,'medium','style_000014.jpg'), 20(15,5,4,'others','style_000019.jpg'), 21(16,1,4,'long','style_000015.jpg'); 22
  • 集計

SQL

1select * from tbl as t2 inner join 2(select ( 3 select id from tbl where t1.genre_id=genre_id order by rand() limit 1 4 ) as id 5from (select distinct genre_id from tbl) as t1 6) as t3 on t2.id=t3.id

投稿2018/11/12 01:33

yambejp

総合スコア114572

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

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

taro_nii_chan

2018/11/12 11:28

なるほど〜。 INNER JOINとSUBQUERY、rand()、distinctをこう組み合わせると欲しいものが出来上がるんですね。見せられて解読せよと言われれば出来ますが自力で作れと言われると中々大変です。 でも勉強になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問