SQLiteでテーブルのレコードにランダムな番号を振る方法

このQ&Aのポイント
  • SQLite3で、テーブル中のレコードをランダムに並び替えた後、その順番で1から番号を入れる方法について教えてください。
  • 例えば、テーブルには以下のようなデータがあるとします。一番最後のレコードから順に1から番号を振りたいです。
  • ブロックで順番に処理を行う方法以外で、効率的かつ迅速にテーブルのレコードにランダムな番号を振る方法を教えてください。
回答を見る
  • ベストアンサー

SQLiteで、ランダムにレコードに番号を振るには

お世話になります。 SQLite3で、テーブル中のレコードをランダムに 並び替えた後、その順番で1から番号を入れて いきたいのですが、それを少手順でできるSQL等は ありますでしょうか。 例えば、 1,りんご,0 2,いちご,0 3,いちじく,0 4,トマト,0 5,ほうれんそう,0 等とあった場合、一番最後の場所に、 3,いちじく,1 5,ほうれんそう,2 2,いちご,3 1,りんご,4 4,トマト,5 …と、1から順に番号を振りたいのです。 勿論、一つ一つ順を追っていけば、できない事ではありませんが、 頻繁に繰り返して行いたいのでできれば軽く、早くしたいのですが…。 良い方法がありましたらお教えください。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.2

> 対人戦でなく、CPUを相手にするゲームなのですが、対戦する相手を > ランダムで順番に対戦相手の中から選ぼうとしています。 > > ただ、それだけなら一件一件ランダムで拾えばいいと思われますが、 > 一度勝ち進んできた対戦相手とさかのぼってもう一度やってみたいと > いう機能を付けてみたいと思っています。 > そのため、どういう順番で対戦相手が出てきたかの履歴が必要になります。 なるほど、そういう背景があるんですね。 でも、それだったらランダムが必要なのはゲームの開始時ではなく新規の対戦相手の選択時ですよね。 自分だったら、現在のテーブル構成でという制約なら 3 番目の列名を「対戦順」と呼ぶとして  (1)ゲーム開始時に全レコードの「対戦順」を未対戦を表す値に設定する。  (2)新規対戦時にはテーブルから「対戦順」が未対戦のものを捜し、その中からランダムに選択する。そののちその選択したレコードの「対戦順」を新規対戦が何番目かの値に書き換える。  (3)過去にさかのぼって対戦する場合には「対戦順」が未対戦ではないものを「対戦順」でソートして捜し、その中から一つを選ばせる。  (4)次の対戦相手は「対戦順」が現在の対戦順 +1 のものを捜し、見つかればその対戦相手を選択する。見つからなければ新規対戦として (2) を行う。 という風にしますしあなたもその案を考慮したでしょうが、そのうえであえて『データベースのフィールドにランダムでインデクスを振る』理由はなにかございますでしょうか。

tatapatank
質問者

補足

ありがとうございます。 いわれてみると、お教えいただいた方法で実現できそうです。 しかし申し訳ございません。 自分の腕試しとしてでもあり、勉強のため…ということでも あるのですが、ゲーム開始のはじめに対戦相手順がはじめから 決まっている場合はどうでしょうか。サッカーの ワールドカップのように、トーナメント方式で勝ち進む場合には、 はじめから対戦相手の組み合わせがわかっているわけです。 飽く迄、一回戦毎に勝ち進むという仕様は変更ありませんが、 ゲームの中の対戦順ごとに、先の相手と戦うために、序盤のうちから 先の相手を見通して戦う…、欲を言ってしまえばきりがありませんが、 履歴だけでなく、先の相手も知ることができるといった感じです。 繰り返すようで申し訳ありませんが、『もし軽く、早く行うためには』 ということですので、特に有効な手段はないというのでしたら、 速度などはあきらめ、一つ一つ行っていこうと思っています。 一度プログラム側でデータを受け取り、ランダムに並び替えた後で、 その順に1から番号を振っていく…という感じでしょうか。 今回は実用性よりは、スキルアップとして取り組めればと思って、 この質問を出させていただきました。確かに、現実的な仕様では ありませんが、『こういう仕様もある』ということで、提案していただければ 幸いです。 よろしくお願いいたします。

その他の回答 (2)

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.3

> #2 補足 ふむ、ならばこちらよりも「その他(データベース) 」カテゴリで質問されると適切な回答が得られるのではないかと思います。 自分も SQL のエキスパートというわけではありませんので。 ただ > 一度プログラム側でデータを受け取り、ランダムに並び替えた後で、 > その順に1から番号を振っていく…という感じでしょうか。 については、ランダムの並び替えは SQL の SELECT 時に ORDER BY random() で行えます。 さすがに特定のキャラをラスボスにとかいうように並び順に手を入れたいならば、それはプログラム側でやる方が適切ではないかと思いますが。

tatapatank
質問者

お礼

お礼が遅れ、大変申し訳ございません。 丁寧な回答、ありがとうございます。 最初の質問の時のように、一つ一つ順を追っていけば できないことではないので、難しいことではないのですが、 ある種『応用』ということで質問させていただきました。 何度もありがとうございました。 教えていただいた例をもとに、再度検討してみたいと思います。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

> テーブル中のレコードをランダムに並び替え ……? SQLite に限らず、RDB にはテーブル中のレコードには並び順なんてありませんが……。 ORDER BY を付けない場合、レコードの並び順なんてデータの追加・削除で変わることは珍しくありません。 なぜレコードをランダムに並べ替えた結果がほしいのか、その結果を使ってやりたいことを、「頻繁に繰り返して行いたい」理由も含めて補足願います。

tatapatank
質問者

補足

ご返答、ありがとうございます。 説明が不足しており、大変申し訳ありません。 この用途は、Androidでミニゲームを作ろうと思っています。 ご存知の通り、AndroidはSQLiteを標準で使用できますし、 ゲームといったことから、『ランダム』という要素は切り離せません。 対人戦でなく、CPUを相手にするゲームなのですが、対戦する相手を ランダムで順番に対戦相手の中から選ぼうとしています。 ただ、それだけなら一件一件ランダムで拾えばいいと思われますが、 一度勝ち進んできた対戦相手とさかのぼってもう一度やってみたいと いう機能を付けてみたいと思っています。 そのため、どういう順番で対戦相手が出てきたかの履歴が必要になります。 今の状況なら、その対戦相手の数も10人そこそこのため、Androidの アプリ本体に配列だのなんだので残してもいいのですが、 自分の腕慣らしの為もかねて、あえてデータベースに順番を残して、 過去にいつでもさかのぼれるようにとしたいのです。 質問文にも書きましたが、一つ一つ行うだけなら、難しいことは ないと思いますが、要はゲームというアプリの為であり、また 自分のスキルの再確認の為でもあり、速度と軽量を重視しています。 ただ、私は技術者ではありません。 用途は以上になりますが、行いたいのは飽く迄 『データベースのフィールドにランダムでインデクスを振る』方法です。 長文になりましたが、よろしくお願いいたします。

関連するQ&A

  • 環境PHP5 Apache2.0 SQLite

    環境PHP5 Apache2.0 SQLite データベースSQLiteに関する質問なのですが、データベース名、テーブル名のみ解っている状態からテーブルで使用されている項目の一覧などは取得できますでしょうか? データベース名 くだもの テーブル名 くだもの リンゴ バナナ イチゴ  1   3   2  このようにテーブルのみ解っている状態から中身を見ずに項目「りんご」、「バナナ」、「イチゴ」を取得したのです。SQLiteで無くとも、他のデータベースで可能でしたらご教授ください。よろしくお願い致します。

    • ベストアンサー
    • PHP
  • 片方のテーブルに存在しないレコードの抽出する方法

    shop1テーブルに存在して、shop2テーブルに存在しないレコードを抽出させたいのですが、 どのようにSQLを書けば良いのでしょうか? よく知らないのですが、SQLでは結合?というジャンルの手法ですか? shop1テーブル nama num みかん 10 りんご 20 なし 30 いちご 50 shop2テーブル name num みかん 55 りんご 44 なし 33

  • access テーブル結合の逆?

    Access2003 お世話になります。SQLで以下のようなデータを取得する場合、上手い方法はあるのでしょうか。なんだかとても簡単な事のような気がするのですが…… テーブルA: ---品名--- りんご みかん もも いちご テーブルB: ---品名--- りんご もも このテーブルBに入力されているレコードをテーブルAから"除外"して、結果として「みかん」と「いちご」だけが欲しいのです。 テーブルBのレコードが少なければ、直接 品名<>"りんご" とか書いてもいいのかもしれませんが、結合のようなSQLで一発でできてしまったりしないでしょうか。 access上で可能なスマートな方法があれば教えていただきたいです。 よろしくお願いいたします。

  • SQLite3でこんな便利なSQLはできますか?

    こんにちは。 SQLite3で次のようなクエリを書けるかどうかご存じの方、教えてください。 文房具の商品レコードを格納したテーブルがあります。 えんぴつ50円、ノート100円、ホチキス150円といった具合です。このテーブルから無作為にレコードを取り出し続けたいのですが、取り出した複数レコードの金額の合計が1000円を超えたところでストップしたいです。1050円でも1200円でもいいのですが、超えたところで止めたいのです。 インターフェイスとしてPHPを予定していて、そこででごにょごにょすればできるのですが、そもそもSQLの時点でこうしたことができるのかご存じの方教えてください。

  • SQLのSELECT文でのランダム抽出について

    SQLのSELECT文でのランダム抽出について データベースSQLiteでSELECT文の結果をランダムに抽出するには ORDER BY RANDOM()を使うようですが、前回ランダムに抽出された順序と同じ結果を得るにはどのようにすればよいでしょうか。 MySQLの場合は、ORDER BY RAND(n)でnの値を同じにすれば、同じ順序で抽出できるようですが、SQLiteでは無理なようです。 今考えているのはRANDOM()で得られた列の一つ(たとえばID)を一時的に別のテーブルを作成して保存後、その一時テーブルを利用するというものですが、もっと良い方法があるのではと思います。 何か別の方法がありましたら、教えていただきたくよろしくお願いいたします。

  • レコードの文字列をフィールド抽出のクエリとして指定

    レコードの文字列として リンゴ ミカン イチゴ となっていたときに、この3つを別のテーブルにあるフィールド名のリンゴ、ミカン、イチゴのみを抽出するクエリをVBAで指定できますか?

  • SQLiteのLike句で抽出できない

    SQLiteのLike句で抽出できないレコードがあります。 原因についてご教授いただけますでしょうか。 以下、操作手順になります。 ■データベースの作成 C:\>sqlite3.exe member.db SQLite version 3.7.15.2 2013-01-09 11:53:05 Enter ".help" for instructions Enter SQL statements terminated with a ";" ■テーブルの作成、レコードの追加 sqlite> create table t_member(name text, age integer); sqlite> insert into t_member values('山田一郎', 25); sqlite> insert into t_member values('田中次郎', 35); sqlite> insert into t_member values('鈴木三郎', 45); ■検索 sqlite> select * from t_member where name like '%一郎'; 山田一郎|25 sqlite> select * from t_member where name like '%次郎'; 田中次郎|35 sqlite> select * from t_member where name like '%三郎'; sqlite> 三郎だけが検索条件に適合しないのは何故でしょうか。 よろしくお願いします。

  • レコードを1件のみ取得した後、検索をやめる方法はあるのでしょうか?

    PostgreSQLのデータベースでテーブルから、 "1件のレコードが見つかった時点で、他のレコードを検索するのをやめる" という事はSQLでできるのでしょうか? 【テーブル名 Fruit 】 | id | option | name |  1    2     りんご  2    1     みかん  3    1     メロン  4    1     バナナ  5    4     いちご 上記のようなテーブルから、optionが1のレコードを検索する時、 どのレコードでもいいので、1件見つけた時点で他にも該当のレコードがあるかという検索の処理をしない。 という事はできるのでしょうか? 出来るのであれば、膨大な数のレコードがある場合、検索の時間が減るのでは無いかと思ったのですが・・・ 現在は下記のSQLのように、OFFSETとLIMITを使用して1件のレコードを取得しています。 SELECT      * FROM      Fruit WHERE      option=1 OFFSET 0 LIMIT 1 このやり方であっているのでしょうか? または他の仕方があるのでしょうか? 教えていただきたいです。 宜しくお願いします。

  • SQLite3にて重みづけを行った抽選のSQL

    お世話になります。 前回の質問にて、説明不足でしたので、 改めて質問させていただきました。 ID,name,point 1.りんご.30 2.みかん.22 3.いちご.18 4.バナナ.13 5.すもも.4 6.マンゴー.1 上記のようなデータがある場合、pointが高いほど 選ばれ易くするような重みづけのある抽選のSQLを 記述したいのですが、その方法を お教えいただけないでしょうか。 データベースはSQLite3(必須)を使用しています。 使用する言語はJava、C#を検討していますが、 極力コードには依存せずに、SQLiteだけで 完結させたいと考えています。 サンプルなどを掲示していただけますと幸いです。 以上、よろしくお願いいたします。

  • SQLで乱数を使った取得の工夫

    お世話になります。 ID,name,point 1.りんご.30 2.みかん.22 3.いちご.18 4.バナナ.13 5.すもも.4 6.マンゴー.1 上記のようなデータがある場合、pointが高いほど 選ばれ易くするようなSQLを記述したいのですが、 その方法をお教えいただけないでしょうか。 ただのランダムであれば、『SELECT * FROM テーブル名 WHERE ID=abs(random()%全レコード数(この場合は6)+1』と すれば、均等にランダムで拾えますが、これを1のりんごのIDほど 取得しやすく、6のマンゴーほど発生しにくくするといった感じです。 以上、よろしくお願いいたします。

専門家に質問してみよう