
お世話になります。質問がふたつあります。
このような、IDとTypeのふたつのカラムで重複しているレコードが多いテーブル「tb」があるとします。
ID Type age
1 1 20
1 2 35
1 3 42
1 2 31
1 3 45
1 2 33
2 1 21
2 3 41
2 1 26
2 2 31
2 1 25
2 1 28
これを、以下のようにしたいのです。
ID Type age
1 1 20
1 2 35
1 3 42
2 1 21
2 2 31
2 3 41
group by ID, Typeとしたところ、
似たような形にはなったのですが、IDとTypeが重複した
ID Type age
1 2 35
1 2 31
1 2 33
のうち、group byによってどのような基準でひとつが選択されるのでしょうか?
レコードの追加が新しいものが選ばれるのでしょうか?
また、ageをランダムでひとつを選択するような書き方はできるのでしょうか。
よろしくお願いします。
No.5ベストアンサー
- 回答日時:
group by 句に無いカラムがどう選択されるかは既にご回答の有るとおり。
要は見つけた順なのだが、indexのアルゴリズムや、挿入削除で物理配置が変わるので、不定となる。
あと、mysql には、集約関数にランダムに取り出す物はないので、サブクエリか、テンポラリーテーブルが必要。mysql 4.1 以降なら、サブクエリでいけそう。最適化も考慮すると以下かな?最後の order by null で既に並んでる物を再度並べ替え作業しないようにして、少々時間短縮。
select id,Type, age
from (select id,Type, age from tb order by id,Type, rand() ) as rand_tbl
group by id,Type
order by null ;
おお、時間短縮まで考慮されたクエリをありがとうございます!
order by null は使ったことがありませんでしたが、
とてもわかりやすくて勉強になります!
ありがとうございました!
No.4
- 回答日時:
きちんとやるならテンポラリなどにおとすことですね
create temporary table tmp(ID int,Type int,age int,unique key(ID,Type));
insert ignore into tmp select * from tb order by rand();
select * from tmp order by ID,Type;
結局SQLでのランダム処理は全データを総なめすることになるので
無駄が多いですけどね。
なるほど、こういう時にテンポラリが使えるのですね。
お恥ずかしながら初心者なもので思い付きませんでした…。
勉強になりました!ありがとうございました!
No.3
- 回答日時:
ちょっと訂正します。
> pk順だったり、insert順だったり、とその時その時の結果の傾向はありますが、
> もう1度同じクエリを発行した結果が同じとは限りません。
>
pk順っぽい、insert順っぽい、とその時その時の結果の傾向はありますが、
もう1度同じクエリを発行した結果が同じとは限りません。
細かいところですが、なんかミスリードさせそうだったので。
No.2
- 回答日時:
order byなしでのselectの順番は保障されていません。
pk順だったり、insert順だったり、とその時その時の結果の傾向はありますが、
もう1度同じクエリを発行した結果が同じとは限りません。
つまり、保障されてないのでランダムとも言えなくはないでしょう。
mysqlに限らず、他のRDBの多くでそうなってます。
また、group byに関しては、
そもそも、グループ化された列や集計関数以外はselectできません。
例で言うなら、group by id,type なので、
selectできるのはid,typeとあと集計関数と定数のみです。
ただ、mysqlではグループ化していない列もselectできます。
しかし、その結果(どれが表示されるか)は保障されていません。
多分、selectが保障できないので、それをグループ化するから保障できないのでしょう。
その上でランダムで出したいなら、
グループ化する前の結果順をランダムにして、それをgroup byするとどうでしょうか。
もっと他に良い方法ありそうですか、ぱっと思いついたのは以下です。
select t.id,t.type,t.age from (select * from tb order by rand()) t group by t.id,t.type order by t.id,t.type;
良いクエリではないと思うので、データが増えた時の性能には十分に気をつけてください。
返事が遅くなり申し訳ありません。
とても詳しい説明ありがとうございます。
教えていただいたクエリで解決いたしました!
お礼申し上げます。
No.1
- 回答日時:
たいてい、group by は、max()、min()、sum()、count()などの集合関数とセットでは?
> これを、以下のようにしたいのです。
これのルールはなんでしょう?
> ageをランダムでひとつを
ACCESSのクエリなら、前記に加え「先頭」「最後」も可能でしょうケド
ランダムは無さそう。
この回答への補足
すみません、説明不足でした。
各IDとTypeのセットをひとつずつ抽出したいのです。
//元データ
create table tb (ID int,Type int,age int);
insert into tb values(1,1,20),(1,2,35),(1,3,42),(1,2,31),(1,3,45),(1,2,33),(2,1,21),(2,3,41),(2,1,26),(2,2,31),(2,1,25),(2,1,28);
//試したもの
select ID, Type, age
from tb
group by ID, Type;
とするとIDとTypeがまとめられますが、どういう基準でageを選んでいるのか、
ランダムにageを選べるのかがわかりません……。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
別のDB(Table)からの複数行の...
-
同じサーバーで、異なるデータ...
-
Unionした最後にGROUP BYを追加...
-
【SQL文】Insert into文で文法...
-
[MySQL] 1対多のリレーションで...
-
DB設計について
-
レコード数が増えすぎた場合の対処
-
MySQLにてCOUNTした値を更にCOUNT
-
カラム名でseqとidではどちらが...
-
同一のユーザー、同一商品のと...
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
1テーブル&複数レコードの更新...
-
SQLサーバから、項目の属性(型...
-
よか石けんの口コミや評判
-
期間の重複を調べるSQL文につい...
-
VIEWの元のテーブルのindexって...
-
inner joinをすると数がおかし...
-
updateを1行ずつ実行したい。
-
select文のwhere句に配列を入れ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
VIEWの元のテーブルのindexって...
-
エラー 1068 (42000): 複数の主...
-
SQLサーバから、項目の属性(型...
-
select文のwhere句に配列を入れ...
-
SQL Left Join で重複を排除す...
-
Access パラメータクエリをcsv...
-
マイクラPC版のコマンドで効率...
-
【Transact-sql】 execの結果を...
-
sqlで、600行あるテーブルを100...
-
SQLにて特定の文字を除いた検索...
-
1テーブル&複数レコードの更新...
-
PL/SQLの変数について
-
WordpressのContact form 7でzi...
-
複数テーブルのGROUP BY の使い...
-
バインド変数について
-
inner joinをすると数がおかし...
-
MySQLのint型で001と表示する方...
-
updateを1行ずつ実行したい。
おすすめ情報