我正在尝试从两个表中选择数据并在分页网格视图中显示该数据。问题是,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)
));
答案 0 :(得分: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的格式来确保查询不复杂:
此外,您还可以确保直接设置这些属性,因此您实际上将查询分解为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
下的表格将被称为{{1 }}。在连接条件中也必须指定任何其他表(非常类似于t
或messages m
),否则您可能会收到messages AS m
警告。
如果您有任何问题,请不要错过CDbCriteria和CActiveDataProvider。
答案 1 :(得分: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;
来获取主题。