-1

2つのテーブルからデータを選択し、そのデータをページ分割されたグリッドビューに表示しようとしています。問題は、YiiがSQL結合を使用してデータを結合していることです(これを行うように指示したため)。そのため、ページあたりのアイテム数が正しく表示されません。

topics明確にするために、私はとから選択してmessages_in_topicsいて、それから参加しています

$criteria->together = true;

これにより、MySQLは各メッセージ(および関連トピック)の行を返します。例:

id_topic    topic    id_messages    message

1           topic1   1              message1_in_topic1
1           topic1   2              message2_in_topic1
1           topic1   3              message3_in_topic1
2           topic2   4              message1_in_topic2
2           topic2   5              message2_in_topic2

トピックは2つしかありませんが、Yiiのページネーターは5つあると考えています。

これを「修正」する最も速い方法は、id_topicフィールドでグループ化することです。とにかく、likeステートメントで検索するwhere条件があるため、これを行うことはできません。

ありがとうございました

編集:

これが私のアクションコードです:

$criteria = new CDbCriteria;

$get_s = Yii::app()->request->getQuery('s', '');
if( $get_s ){
    $criteria->compare("topic_title", $get_s, true);
    $criteria->compare("message_text", $get_s, true, 'OR');
}

$criteria->with = array('messages');
$criteria->addCondition(array( ......  )); <--- some rules like if the topic is validated...

$dataProvider = new CActiveDataProvider('Topics', array(
    'criteria'=>$criteria,
    'pagination=>array('pageSize'=>15)
));
4

2 に答える 2

1

実際、表示されている情報はメッセージに関するものです。繰り返されるトピック値は、これらのトピックがメッセージに対応する関連データであるためです。

結果でGROUPBYを使用するようにクエリに指示することができます...

SELECT t.id_topic, t.topic, COUNT(m.id_messages)
  FROM topics t LEFT JOIN messages m ON t.id_topic = m.id_topic
GROUP BY t.id_topic

このようにして、多かれ少なかれ、トピックごとのメッセージの数を表示できます。SQLを見せていただければ、もっとお手伝いできます。

編集:あなたのコードを見た後、ここに私の推測があります:$ criteria = new CDbCriteria;

$get_s = Yii::app()->request->getQuery('s', '');
if( $get_s ){
    $criteria->compare("topic_title", $get_s, true);
    $criteria->compare("message_text", $get_s, true, 'OR');
}

$criteria->with = array('messages');
$criteria->addCondition(array( ......  )); <--- some rules like if the topic is validated...

$dataProvider = new CActiveDataProvider('Topics', array(
    'criteria'=>$criteria,
    'pagination=>array('pageSize'=>15)
));

CDbCriteriaの3つの基本的なプロパティのみを使用してクエリを注ぐことで、クエリがyiiのフォーマットによって複雑にならないようにすることができます。

  1. $ criteria-> selectは、まさに選択したい列のリストです。
  2. $ criteria-> conditionはまさにWHERE条件です。文字列を使用すると、ここに入力した正確な条件を使用できるため、配列よりも文字列を使用することを正直に好みます。
  3. $ criteria-> joinは、CActiveDataProviderコンストラクターで指定した$ model-> tableName()の直後に付加されます。
  4. クエリの最後に$criteria->groupが追加されます。必要なのは、グループ化列を指定することだけです。

また、これらのプロパティを直接設定することもできるので、実際にクエリをCDbCriteriaオブジェクトに分解します。例えば:

SELECT t.id_topic, t.topic, COUNT(m.id_messages)
  FROM topics t LEFT JOIN messages m ON t.id_topic = m.id_topic
GROUP BY t.id_topic

このようになります

/*1*/ $criteria->select = 't.id_topic, t.topic, COUNT(m.id_messages)';
/*2*/ $criteria->condition = 't.topic_title LIKE %'.$get_s.'% OR ...';/* add your conditions here*/
/*3*/ $criteria->join = 'LEFT JOIN messages m ON t.id_topic = m.id_topic'; //Full join statement here, including the nature of the join.
/*4*/ $criteria->group = 't.id_topic';

重要Topics:クラス名をコンストラクターに渡すためCActiveDataProvider、下のテーブルTopicsはとして知られることに注意してtください。他のテーブルも結合条件で指定する必要があります(messages mまたはとほとんど同じです)。指定しないと、警告が表示される場合があります。messages AS mcolumn xxxx is ambiguous

質問がある場合は、 CDbCriteriaCActiveDataProviderに目を向ける機会を逃さないでください。

于 2012-11-14T17:35:14.573 に答える
0

問題はページネーターではなく、クエリすることです。クエリを実行する場合:

SELECT *
FROM topics as t
INNER JOIN messages_in_topics as mt
    ON mt.topics_id = t.id
INNER JOIN messages as m
    ON m.id = mt.messages_id

上記の例に示すように、5つの結果が得られます。

さらに重要なことに、あなたは何をしようとしていますか?

また、テーブルにはMANY_MANY関係(message1には2つのトピックがあり、topic1には3つのメッセージがあります)が示されています。データベースは正しい方法で設定されており、モデルの関係はそれに応じて構成されていますか?

各トピックのすべてのメッセージを1行で表示しようとしていますか?

すべてのトピックを表示し、そのトピックを含む各メッセージを一覧表示しようとしていますか?

リレーションが正しく設定されていると仮定すると、:を使用$messages=$topics->messages;して、すべてのメッセージがリストされた配列を取得できます。

逆に$topics=$messages->topics;、トピックを取得するために行うことができます。

于 2012-11-14T17:15:48.673 に答える