- ベストアンサー
SQLiteでテーブルのレコードにランダムな番号を振る方法
- SQLite3で、テーブル中のレコードをランダムに並び替えた後、その順番で1から番号を入れる方法について教えてください。
- 例えば、テーブルには以下のようなデータがあるとします。一番最後のレコードから順に1から番号を振りたいです。
- ブロックで順番に処理を行う方法以外で、効率的かつ迅速にテーブルのレコードにランダムな番号を振る方法を教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> 対人戦でなく、CPUを相手にするゲームなのですが、対戦する相手を > ランダムで順番に対戦相手の中から選ぼうとしています。 > > ただ、それだけなら一件一件ランダムで拾えばいいと思われますが、 > 一度勝ち進んできた対戦相手とさかのぼってもう一度やってみたいと > いう機能を付けてみたいと思っています。 > そのため、どういう順番で対戦相手が出てきたかの履歴が必要になります。 なるほど、そういう背景があるんですね。 でも、それだったらランダムが必要なのはゲームの開始時ではなく新規の対戦相手の選択時ですよね。 自分だったら、現在のテーブル構成でという制約なら 3 番目の列名を「対戦順」と呼ぶとして (1)ゲーム開始時に全レコードの「対戦順」を未対戦を表す値に設定する。 (2)新規対戦時にはテーブルから「対戦順」が未対戦のものを捜し、その中からランダムに選択する。そののちその選択したレコードの「対戦順」を新規対戦が何番目かの値に書き換える。 (3)過去にさかのぼって対戦する場合には「対戦順」が未対戦ではないものを「対戦順」でソートして捜し、その中から一つを選ばせる。 (4)次の対戦相手は「対戦順」が現在の対戦順 +1 のものを捜し、見つかればその対戦相手を選択する。見つからなければ新規対戦として (2) を行う。 という風にしますしあなたもその案を考慮したでしょうが、そのうえであえて『データベースのフィールドにランダムでインデクスを振る』理由はなにかございますでしょうか。
その他の回答 (2)
- hitomura
- ベストアンサー率48% (325/664)
> #2 補足 ふむ、ならばこちらよりも「その他(データベース) 」カテゴリで質問されると適切な回答が得られるのではないかと思います。 自分も SQL のエキスパートというわけではありませんので。 ただ > 一度プログラム側でデータを受け取り、ランダムに並び替えた後で、 > その順に1から番号を振っていく…という感じでしょうか。 については、ランダムの並び替えは SQL の SELECT 時に ORDER BY random() で行えます。 さすがに特定のキャラをラスボスにとかいうように並び順に手を入れたいならば、それはプログラム側でやる方が適切ではないかと思いますが。
お礼
お礼が遅れ、大変申し訳ございません。 丁寧な回答、ありがとうございます。 最初の質問の時のように、一つ一つ順を追っていけば できないことではないので、難しいことではないのですが、 ある種『応用』ということで質問させていただきました。 何度もありがとうございました。 教えていただいた例をもとに、再度検討してみたいと思います。
- hitomura
- ベストアンサー率48% (325/664)
> テーブル中のレコードをランダムに並び替え ……? SQLite に限らず、RDB にはテーブル中のレコードには並び順なんてありませんが……。 ORDER BY を付けない場合、レコードの並び順なんてデータの追加・削除で変わることは珍しくありません。 なぜレコードをランダムに並べ替えた結果がほしいのか、その結果を使ってやりたいことを、「頻繁に繰り返して行いたい」理由も含めて補足願います。
補足
ご返答、ありがとうございます。 説明が不足しており、大変申し訳ありません。 この用途は、Androidでミニゲームを作ろうと思っています。 ご存知の通り、AndroidはSQLiteを標準で使用できますし、 ゲームといったことから、『ランダム』という要素は切り離せません。 対人戦でなく、CPUを相手にするゲームなのですが、対戦する相手を ランダムで順番に対戦相手の中から選ぼうとしています。 ただ、それだけなら一件一件ランダムで拾えばいいと思われますが、 一度勝ち進んできた対戦相手とさかのぼってもう一度やってみたいと いう機能を付けてみたいと思っています。 そのため、どういう順番で対戦相手が出てきたかの履歴が必要になります。 今の状況なら、その対戦相手の数も10人そこそこのため、Androidの アプリ本体に配列だのなんだので残してもいいのですが、 自分の腕慣らしの為もかねて、あえてデータベースに順番を残して、 過去にいつでもさかのぼれるようにとしたいのです。 質問文にも書きましたが、一つ一つ行うだけなら、難しいことは ないと思いますが、要はゲームというアプリの為であり、また 自分のスキルの再確認の為でもあり、速度と軽量を重視しています。 ただ、私は技術者ではありません。 用途は以上になりますが、行いたいのは飽く迄 『データベースのフィールドにランダムでインデクスを振る』方法です。 長文になりましたが、よろしくお願いいたします。
補足
ありがとうございます。 いわれてみると、お教えいただいた方法で実現できそうです。 しかし申し訳ございません。 自分の腕試しとしてでもあり、勉強のため…ということでも あるのですが、ゲーム開始のはじめに対戦相手順がはじめから 決まっている場合はどうでしょうか。サッカーの ワールドカップのように、トーナメント方式で勝ち進む場合には、 はじめから対戦相手の組み合わせがわかっているわけです。 飽く迄、一回戦毎に勝ち進むという仕様は変更ありませんが、 ゲームの中の対戦順ごとに、先の相手と戦うために、序盤のうちから 先の相手を見通して戦う…、欲を言ってしまえばきりがありませんが、 履歴だけでなく、先の相手も知ることができるといった感じです。 繰り返すようで申し訳ありませんが、『もし軽く、早く行うためには』 ということですので、特に有効な手段はないというのでしたら、 速度などはあきらめ、一つ一つ行っていこうと思っています。 一度プログラム側でデータを受け取り、ランダムに並び替えた後で、 その順に1から番号を振っていく…という感じでしょうか。 今回は実用性よりは、スキルアップとして取り組めればと思って、 この質問を出させていただきました。確かに、現実的な仕様では ありませんが、『こういう仕様もある』ということで、提案していただければ 幸いです。 よろしくお願いいたします。