2012-04-01 8 views
5

私は共同翻訳ウィジェットを作成する方法を探していました。だから、私はmysqlデータベースとテーブル(翻訳と呼ばれる)と、ユーザーが一度に1ページを翻訳できるようにするための小さなスクリプトを持っています。mysqlクエリからランダムな行を出力します

しかし、私は自分のスクリプトでは納得できません。私はそれが十分に効率的だとは思わない。まず、mysqlは空の 'en'カラムを持つすべての行を取得し、そのうち1つは画面でしばらく表示されます。これを行う他の方法はありますか?

//Retrieve all the data from the "translations" table 
$result = mysql_query("SELECT * FROM translations WHERE en IS NULL OR en=''") or die(mysql_error()); 

$Randnum=rand(0,mysql_num_rows($result)-1); //Gets a random number between 0 and the maximum number of rows 
$i=0; //Start to 0 
while($Col = mysql_fetch_array($result)) //While there are rows to evaluate 
    { 
    if ($i==$Randnum) 
     { 
     echo "\"".$Col['es']."\"<br><br>Translate it to English: <br>"; 
     } 
    $i++; 
    } 

私は "エコー$コル[$ Randnum] [ 'ES']" または "エコー$大佐$ Randnum [ 'ES']" のようなものを探していたの代わりに使用した:これはコードです全体のwhileループは単一のランダムな行を出力します。これをどのように実装できますか?これは単なる最適化の問題です。 $ Colに1行だけ乱数と空の 'en' colを代入するスクリプトやアイデアがあれば、それはさらに良いでしょう! (私はそれがこの最後のビットが可能ではないと思う)。 「行」はテキストなので、実装方法はわかりませんother methods ORDER BYで数字を使用しているのを見てきました。

答えて

7

クエリでORDER BY RAND() LIMIT 1を使用すると、データベースからランダムな行を1つフェッチできます。

+0

+1最初のもののために、それは 'RAND()'だが、:) –

+0

それもテキストで動作しますか?それが動作しても、rand()が言ったように最初のASCIIを持つテキストは選択されませんか? (たとえば、多くの行が 'H'で始まる場合は、rand()が72であるたびに最初の行のみを選択しません) –

+0

@FrankPresenciaFandos:これはテーブル内のデータとはまったく関係ありません。内部的には、各行に対して乱数を生成し、その数で注文します。 – ThiefMaster

2

これを行うには、いくつかの方法があります

SELECT * FROM translations WHERE en IS NULL OR en='' ORDER BY rand() LIMIT 0,1 
1

クエリ側でそれを確認します。

@ ThiefMasterの回答はうまくいくでしょうが、 "order by rand()"は大きなテーブルでかなりのパフォーマンス上の問題があります。だから、あなたが成長したいと思うサイズのおおよそのサンプルデータをテーブルに埋め込み、パフォーマンスをテストします。それが問題でないなら、それをそのまま残してください - 早すぎる最適化はすべての悪の根源です!

alternativesがあります。 2つの別々のクエリを実行することに依存しています。しかし、あなたがインデックスを持っていると仮定すると、それは問題ではありません。あなたのscenarionのために作り直し

、これは次のようになります。

mysql_query('SELECT @count := COUNT(*) FROM translations WHERE en IS NULL OR en='''); 
mysql_query('SET @offset = CONVERT(FLOOR(RAND() * @count), SIGNED)'); 
mysql_query('PREPARE mystatement FROM "SELECT * FROM translations WHERE en IS NULL OR en='' LIMIT ?, 1"'); 
$res = mysql_query('EXECUTE mystatement USING @offset'); 
$row = mysql_fetch_assoc($res); 
print_r($row); 
+0

将来このテーブルが2000/3000ローよりも大きくなることは期待しませんが、情報を拡張していただきありがとうございます。私は引用符が早すぎる最適化がすべての悪の根源だと気に入った。 –

+0

それは私のものではない - 誰かがかなり早い時期に "時期尚早"を置くと、音が悪くなると指摘した... –

+0

申し訳ありませんが、私は感謝の言葉をいただきありがとうございました。インターネット (; –

関連する問題