2

元の質問:

現在、でZend Frameworkを使用してZend_Db_*おり、テーブルから3つのランダムな行を選択しています。

$category->getTable()->select()->order(new Zend_Db_Expr('RAND()'))->limit('3')

はどこ$categoryにありますかZend_Db_Table_Row。3つのランダムな行を取得したいのですが、これらの3つの行を。という名前の列の順に並べていますname

を次のように変更し->order()ても効果はありませんでした。

->order(array(new Zend_Db_Expr('RAND()'), 'name ASC'))

エントリはまだ順序付けられておらず、ランダムに表示されているためです。

Zend Frameworkソリューションは高く評価されていますが、プロジェクトに適合するように他のソリューションを適応させることができます。


RAND()の使用に伴うスケーリングの問題を認識しています。データベースが問題になるほど大きくなることはありません。データベースを維持することを心配する必要はありません。ロボットは、これから説明します。長く死んでください!:-P


答え

これがZend_Db_Selectを使用して最終的にどのように完了したのか疑問に思っている人のために、これはZend_Db_Select内のサブ選択を使用することになったものです($category->findDefault_Model_projects()依存する行セットを見つけるために使用していましたが、select()をZF-6461が問題を修正するまで副選択します、私は私が持っているもので立ち往生しています):

$projects = new Default_Model_Projects();
$subselect = $projects->select()->order(new Zend_Db_Expr('RAND()'))->limit('3')->where('cid = ?', $category->id, Zend_Db::INT_TYPE);
$db = $projects->getAdapter();
$select = $db->select()->from(array("c" => new Zend_Db_Expr("({$subselect})")))->order('name');

$stmt = $select->query();
$projects = $stmt->fetchAll();

生成されるSQLは次のとおりです。

SELECT `c`.* FROM (SELECT `projects`.* FROM `projects` WHERE (cid = 1) ORDER BY RAND() LIMIT 3) AS `c` ORDER BY `name` ASC

そこから、$ projectsには、他のデータベースクエリと同じように繰り返すことができる標準の行セットが含まれていますが、それを行わないのは、テーブル固有の行/行セットクラスに固定することだけです。

4

4 に答える 4

4

このクエリは各行にランダムな値を生成し、それに基づいて行を並べ替え、ランダムな値が等しい場合にのみ名前で並べ替えるため、最初の解決策は正しくありません(これは非常にありそうにありません)。

この問題は、以下のようなサブクエリで解決できます。

select * from (select * from categories order by rand() limit 3) c order by name

これをZend_Db言語に翻訳する作業はあなたに任せています。

于 2009-07-17T19:59:17.700 に答える
1
$subQuery = $this->select()->from('picture')->order(new Zend_Db_Expr('RAND()'))->limit(count($this->selectAll()));
$select->setIntegrityCheck(false)
       ->from($subQuery);

これは私がしたことであり、それは機能します。乾杯!

于 2011-12-21T15:37:43.720 に答える
0

データを名前で並べ替える行セットサブクラス関数を作成してみませんか?

于 2009-07-18T09:51:23.397 に答える
0

これを試して:

$select = $this->select();
$select->order('RAND(), name');
$select->limit(3);
return $this->fetchAll($select);

それはここで私にとってはうまくいくので、あなたにとってもうまくいくはずです。

于 2009-07-18T12:45:15.337 に答える