简体   繁体   中英

Yii2 using ActiveQuery that uses sub-query on same Model

I have a Comments table that have parent_id foreign key that points to itself to enable threaded comment.

Comments
id INT UNSIGNED NOT NULL
parent_id INT UNSIGNED NULL
comment TEXT NOT NULL
created_time DATETIME NOT NULL

The original ActiveQuery is like this

class CommentActiveQuery extends \yii\db\ActiveQuery {
    public function andWhereIsNotRemoved() {
        return $this->andWhere(['isRemoved' => Comment::STATUS_IS_NOT_REMOVED]);
    }

    public function andWhereParentIdIs($parentId) {
        return $this->andWhere(['parentId' => $parentId]);
    }

    public function orderByNewestCreatedTime() {
        return $this->orderBy(['createdTime' => SORT_DESC]);
    } 
}

Now I want to sort the comments by the newest active reply.

The query is basically like this

SELECT `*`, `last_reply_time` 
    FROM `Comments` 
    WHERE `parent_id` IS NULL 
    ORDER BY `last_reply_time` DESC;

I'm thinking the last_reply_time is a subquery

SELECT MAX(created_time) 
   FROM `Comments` 
   WHERE `parent_id` = :something

How to build this using the CommentActiveQuery above. The farthest I can get is like this

public function orderByNewestActiveChildCreatedTime() {
    return $this->addSelect([
            'last_reply_time' => $subQuery
           ])->orderBy(['last_reply_time' => SORT_DESC]);
} 

With what should I replace the $subQuery variable above? Or is there a better way?

$subQuery = new \yii\db\Query();
$subQuery->select(["max(subQ.created_time)"]);
$subQuery-> from('comments subQ');
$subQuery->where([
    'parent_id' => $parentId
]);

$query = new \yii\db\Query();
$query->select([
    'C.*',
    $subQuery
]);
$query->from('Comments C');
$query->andWhere(
    'parent_id is Null'
);


$command = $query->createCommand();

 /*

   Printing the command will result following sql  with $parentId = 1     

   SELECT
        `C`.*, (
         SELECT
            max(subQ.created_time)
         FROM
            `comments` `subQ`
         WHERE
             `parent_id` =: qp0
         ) AS `1`
    FROM
         `Comments` `C`
    WHERE
         parent_id IS NULL

*/

print_r($command->sql);

I am not sure about ORDER BY last_reply_time DESC; Assuming last_reply_time is db table attribute and is different from the subquery. You can simply add orderBy in the query by doing $query->orderBy('last_reply_time DESC')

I hope this would be helpful to you.Cheers :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM