4

我想获得表的最后 20 个条目,但按 id 升序排列。

在 Sql 中它不是很复杂:

SELECT * 
FROM (SELECT * FROM comments
      WHERE postID='$id' 
      ORDER BY id DESC 
      LIMIT 20) t
ORDER BY id ASC;

但我想用我的 yii 模型来做,比如:

Comment::model()->findAll($criteria)

但我真的不知道我应该在我的 CDbCriteria 中放什么!

4

3 回答 3

10
$models = Comment::model()->findAll(array(
    "condition" => "WHERE postID = '".$id."'",
    "order" => "id DESC",
    "limit" => 20,
));

将获得最后 20 个。现在您想订购由 id ASC 设置的记录正确吗?您是否没有其他字段可以订购类似的结果(可能是日期或创建的字段?)例如:

"order" => "id DESC, created ASC"

取消二级排序,但为什么不直接使用数组反转呢?

$models = array_reverse($models);
于 2012-10-17T20:05:42.873 回答
4

array_reverse如果您考虑使用此 sql,则有一种不使用的方法:

SELECT * FROM `comments` `t` 
WHERE id 
in (SELECT id 
     FROM (SELECT id FROM comments Where postID = xyz ORDER BY id DESC LIMIT 20) 
    as q) 
ORDER BY id ASC

在标准中将变为:

$criteria=new CDbCriteria();
$criteria->condition='id in (SELECT id FROM (SELECT id FROM comments Where postID='.$id.' ORDER BY id DESC LIMIT 20) as q)';
$criteria->order='id ASC';

更新

使用您的原始查询,您还可以使用findBySql

$sql='SELECT * FROM (SELECT * FROM comments  WHERE postID= :postid  ORDER BY id DESC LIMIT 20) q ORDER BY id ASC';
$params=array('postid'=>$id);
$comments=Comment::model()->findAllBySql($sql,$params);

这个查询的性能比我之前的查询要好。

于 2012-10-17T20:44:07.037 回答
2

升级版:

请注意,一般来说,其他一些解决方案比我的要好。

使用offset会降低查询的性能。请参阅:http ://www.slideshare.net/Eweaver/efficient-pagination-using-mysql以及为什么 MYSQL 更高的 LIMIT 偏移会减慢查询速度?

因此,当数量Comments会增加时,您可以获得性能下降。


使用offset功能呢?

    $model = Comment::model();

    $condition = 'postID =' . $id;
    $limit = 20;
    $totalItems = $model->count($condition);

    $criteria = new CDbCriteria(array(
        'condition' => $condition,
        'order' => 'id ASC',
        'limit' => $limit,
        'offset' => $totalItems - $limit // if offset less, thah 0 - it starts from the beginning
    ));

    $result = $model->findAll($criteria);
于 2012-10-17T20:48:18.543 回答