如何按关联顺序获取数据?

时间:2021-06-08 12:30:41

标签: cakephp cakephp-4.x

我有两张桌子。

  1. 聊天室
  2. chat_pinned_rooms

chat_rooms 通过 has_manychat_pinned_roomschat_room_id 关系。

现在我想按 chat_roomschat_pinned_rooms 数据进行排序(排序)。

我尝试过以下查询:

$this->ChatRooms->find()
    ->contain('ChatPinnedRooms', function ($q) {
            return $q
                ->where(['user_id' => $this->Auth->id])
            ;
        })
    ->order([
        'ChatRooms.ChatPinnedRooms.id' => 'ASC'
    ])
    ->all()
;

如果我在包含中使用这个顺序,它只会对这些关联中的数据进行排序。但我需要按关联顺序对父表数据 (chat_rooms) 进行排序。

1 个答案:

答案 0 :(得分:2)

如果您想先对有 1 个或多个关联 ChatRoomsChatPinnedRooms 进行排序,那么您可以加入 ChatPinnedRooms 关联,为每个 ChatRooms.id 创建组,并根据例如这些组中 ChatPinnedRooms 的计数进行排序,大致如下:

$query = $this->ChatRooms
    ->find()
    ->leftJoinWith('ChatPinnedRooms', function ($q) {
        return $q
            ->where(['user_id' => $this->Auth->id]);
    })
    ->group('ChatRooms.id')
    ->orderAsc(function (
        \Cake\Database\Expression\QueryExpression $exp,
        \Cake\ORM\Query $q
    ) {
        return $exp->gte(
            $q->func()->count('ChatPinnedRooms.id'),
            1
        );
    });
LEFT JOIN ... ChatPinnedRooms ...
GROUP BY ChatRooms.id
ORDER BY COUNT(ChatPinnedRooms.id) >= 1 ASC

(如果您想在结果中包含固定房间,您也需要 contain() 它们,就像在您的示例中一样)或者您可以使用计数器缓存,以便您在其中有一个具体的列ChatRooms 保存关联记录的计数,然后您可以使用这些计数进行排序,例如:

// in `ChatPinnedRoomsTable` class
$this->addBehavior('CounterCache', [
    'ChatRooms' => ['chat_pinned_rooms_count'],
]);
$query = $this->ChatRooms
    ->find()
    ->order([
        'chat_pinned_rooms_count >=' => 1,
    ]);

另见

相关问题