5

これが状況です。バックエンドとして MySQL と MSSQL の両方と互換性のある Zend_Framework で記述されたアプリケーションがあります。現在、ZF は 2 つの言語間の多くの SQL の不一致/相違点を解決するのに非常に優れていますが、私はまだこれを理解する必要があります。

目的は、テーブルから 1 つのランダムなレコードを選択することです。これは非常に単純なステートメントです。

たとえば、select ステートメントを次に示します。

$sql = $db->select()
      ->from("table")
      ->order("rand()")
      ->limit(1);

MySQL の sql は次のとおりであるため、これは MySQL データベース テーブルに対して完全に機能します。

SELECT `table`.* FROM `table` ORDER BY rand() ASC

一方、MSSQL はnewid()関数を使用してランダム化を行います。

適切な順序付けを使用する必要があることを認識させるために、 order()関数に渡すことができるヘルパーのようなものはありますか? 私はドキュメントを検索し、zfforums でいくつかのヒントを見つけましたが、確実なものは何もありませんでした。

私が見つけたものの1つは次のとおりです。

ORDER BY RANDOM() が機能しない- ZFForums.com

彼らは以下を使用しています:

$res = $db->fetchAll(
'SELECT * FROM table ORDER BY :random',
array('random' => new Zend_Db_Expr('RANDOM()')
);

それは機能します...しかし、私は選択ステートメントを入力して文字列を置換することで作成するつもりはありません。同じZend_Db_Selectオブジェクトに保持しようとしています。また、ステートメントに を渡そうとしましたが、失敗しZend_Db_Expr('RANDOM()')ます。->order()彼は答えを見つけるための理論的な解決策も投稿していますが、私は $db->fetch() 呼び出しを変更して、これが含まれている関数を書き直すつもりはありません。

何か案は?

4

2 に答える 2

14

関数をテーブルにすばやく抽象化できます-使用しているアダプターを誰が知っていますか:

class MyTable extends Zend_Db_Table_Abstract {
   public function randomSelect($select=null) {
     if ($select === null) $select = $this->select();
     if (!$select instanceOf Zend_Db_Select) $select = $this->select($select);
     $adapter = $this->getAdapter();
     if ($adapter instanceOf Zend_Db_Adapter_Mysqli) {
       $select->order(new Zend_Db_Expr('RAND()'));
     } else if ($adapter instanceOf Zend_Db_Adapter_Dblib) {
       $select->order(new Zend_Db_Expr('NEWID()'));
     } else { 
       throw new Exception('Unknown adapter in MyTable');
     }
     return $select;
  }
}

$someSelect = $table->select();
// add it to an existing select
$table->randomSelect($someSelect);

// or create one from scratch
$select = $table->randomSelect();

また、紛失した記事をどこかで見つけたので、次のようなことを試すことをお勧めします。

$select->order(new Zend_Db_Expr('0*`id`+RAND()));

MSSQL のクエリ オプティマイザーを妨害し、それをだまして各行の新しい値を計算させます。

于 2009-09-25T02:28:33.097 に答える
2

クラス My_Db_Expr_Rand を作成し、Zend_Db_Expr を拡張します。アダプターに基づいて、どちらか一方を返します。

于 2009-09-24T22:00:27.293 に答える