
レコードをグループ化して、そのグループから1レコードをランダムに選択する方法はないでしょうか?
具体的には、たとえば以下のようなことです。
以下のようなテーブルがあるとします。
組 氏名
-----------------
A組 鈴木
A組 木村
B組 山田
B組 佐藤
B組 田中
C組 石井
C組 井上
D組 田口
このテーブルから、各組から代表を1人ずつランダムに選びたいです。
たとえば、
A組 鈴木
B組 田中
C組 石井
D組 田口
というように、A組には2人いますが1人をランダムに、B組には3人いますが1人をランダムに、…、という感じです。
集合関数には合計や平均などの数学関数はあるのですが、このようなことを実現するものが見あたりません。
現在は、まず先に組でグループ化したクエリを実行し、A組から順番に
SELECT ~ WHERE 組="A組" ORDER BY RND() LIMIT 1
を実行、次に
SELECT ~ WHERE 組="B組" ORDER BY RND() LIMIT 1
…
というように、いちいち全組分を繰り返していますが、もっと良い方法がありましたら、ご教授お願いいたします。
No.2ベストアンサー
- 回答日時:
order by してから group by すればいいじゃん!とおもったらできないんですね。
よく考えればそりゃそうなんですけど
ソートしてからグループ化ってのは確かにRDBとして効率わるいし。
というわけで、非効率ではありますが、ヒープで処理してみてはいかがですか?
CREATE TABLE `tmp_table` TYPE=HEAP SELECT `*` FROM `org_table` ORDER BY RAND();
SELECT `*` FROM `tmp_table` GROUP BY `class`;
DROP TABLE `tmp_table`;
競合とかきになりますが、所詮ヒープだし。
ご回答ありがとうございます。
今は、ご提案いただいたのと同じような、HEAPテーブルではないですがTEMPORARY TABLEを作って、ORDER BY RANDを付けてコピーしておいて、その後にGROUP BYする、という方法を取ることにしています。
やはりHEAPテーブルは競合が気になりますので、同時に実行されたことを考えてTEMPORARY TABLEにしました。
まぁ結果的に「order by してから group by すればいいじゃん」の方法なんですけどね。2段階になっただけで。
ご指摘のように効率的じゃないかもしれませんが、
SELECTの入れ子とか使えたら楽なんだろうけど、とりあえず、これしかないのかなと…。
それにしても、このような要求ってよくありそうなんですがねぇ…。
No.1
- 回答日時:
結果を後で、分解しないといけませんが、
SELECT 組,MAX(CONCAT(CAST(RAND() AS CHAR),CONCAT('-',氏名)))
FROM テーブル
GROUP BY 組;
というのは、どうでしょう。
ご回答ありがとうございます。
なるほどつまり、グループ化の際にグループ内の要素に数値をランダムにふって、その最大を取り出す、ということですね?
早速試してみようと思ったのですが、なぜか文法エラー、調べてみると、今借りているサーバーのMySQLのバージョンが3.23.56で、CASTが使えないとのこと…。何か別の方法でCASTのようなことをすればよさそうですが。
しかし、せっかくご回答いただいたのに恐縮なのですが率直に申し上げると、
後で分解するということは、全組分のループをすることになり、質問文に書いた、組ごとにランダムに1つ選ぶ処理と、結局は大差がないような気がしまして…。
できればループなどは使わずSQLだけで抽出できたらと思うのですが。
このような処理ってよくありそうなんですが、常套手段のようなものはないのでしょうか…。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
一つ前に戻るには…
-
「テーブルに座って……」という...
-
AccessのSQL 部分一致したデー...
-
テーブルで一番古いレコードだ...
-
降順で並び替えて昇順で受け取...
-
SQLで複数列のデータを複数行に...
-
SQLでUPSERTを一度に複数行やる...
-
外部キーだけのテーブル(主キ...
-
飲み会で、座敷orテーブルどち...
-
会社の飲み会の幹事になり、座...
-
SQLでSUMなどの関数でデータが...
-
テーブルに存在しない列をselec...
-
ORA-01401が表示され、データが...
-
コンボボックスにレコードセッ...
-
まるいテーブル 円い 丸い 漢字...
-
面接のときテーブルが正面に。...
-
SELECT 文の NULL列は?
-
トリガって、自分自身のテーブ...
-
SQL、2つのテーブルで条件一致...
-
DBからタブ区切りのCSVデータを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
一つ前に戻るには…
-
グループからランダムに抽出す...
-
最大値を持つレコードを削除したい
-
【ストアドプロシージャ】条件...
-
mysqlでJOIN文
-
テーブル作成時のNULLの列につ...
-
ビューに追加・削除が出来ません。
-
PHP上のSQLで、SELECT文をいく...
-
update文の副問い合わせ使用
-
1列について重複行を除いて全列...
-
外部キー、親を調べるにはshow ...
-
副問い合わせの限界値はどれく...
-
mysqlのフィールド名
-
矛盾していないでしょうか?
-
MySQL INSERT文 エラー
-
「テーブルに座って……」という...
-
AccessのSQL 部分一致したデー...
-
降順で並び替えて昇順で受け取...
-
外部キーだけのテーブル(主キ...
-
Accessでデータシートに同じデ...
おすすめ情報