-1

我正在尝试从两个表中选择数据并在分页网格视图中显示该数据。问题是 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 字段分组,无论如何,我不能这样做,因为有一个 where 条件可以使用like语句进行搜索。

谢谢

编辑:

这是我的操作代码:

$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

实际上,发生的情况是显示的信息与您的消息有关。重复的主题值是因为这些主题是消息对应的相关数据。

您可以尝试告诉您的查询在结果中使用 GROUP BY ...

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 的三个基本属性来确保查询不会被 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 mor messages AS m),否则您可能会收到column 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 条消息),您的数据库设置是否正确,您的模型关系是否相应配置?

您是否试图在一行中显示每个主题中的所有消息?

您是否尝试显示所有主题并列出包含该主题的每条消息?

假设您正确设置了关系,您可以使用:$messages=$topics->messages;并获取一个包含所有列出消息的数组。

相反,你可以做得到$topics=$messages->topics;主题。

于 2012-11-14T17:15:48.673 回答