CakePHP 3 ORM - 基于两个不同相关表中的两列进行排序

时间:2016-09-09 20:31:32

标签: sql cakephp orm cakephp-3.0

目前我正在尝试实现时间轴功能,该功能需要在两个相关表中对创建的列进行排序,并相应地更新父表(在我的案例中为图片)。

更具体地说,我有一张有很多评论的图片表。我想根据评论和图片表的创建列中的最新时间戳对图片进行排序。

我有以下查询,它检索必要的数据,但没有正确排序:

public function getPicturesAndCommentsOfUser($userId){
    return $this->find()
        ->contain([
            'Comments' => function ($q){
                return $q
                    ->contain(['Users' => function ($q) {
                        return $q->select($this->select);
                    }])
                    ->order(['Comments.created' => 'ASC']);
            },
            'Users' => function ($q) {
                return $q->select($this->select);
            },
            'Albums'
        ])
        ->matching('Albums.Users', function ($q) use ($userId) {
            return $q
                ->where(['Users.id' => $userId]);
        });
}

我的问题是如何结合Pictures.created和Comments.created的顺序。我已经尝试在 - > gt; contains(['Comments'])和最后一次匹配调用后链的最外部调用order函数。我似乎无法弄清楚如何将两个表相互关联,以便我可以对它们进行排序。

此外,我在其他来源(like this one)中读到我可以使用union语句,但我能找到的关于该选项的所有信息都是它可以用于不相关的表,而不是相关的。

任何人都可以就如何解决这个问题给我一些指示?

1 个答案:

答案 0 :(得分:0)

首先,你的目的应该是明确的。哪种订购优先考虑? Pictures.createdComments.created?您无法根据这两者对结果进行排序。当你做这样的事情时:

$this->Comments->find()->order(['Pictures.created' => 'ASC'])->
    order(['Comments.created' => 'ASC']);

仅保证Comments.created的排序。如果两条评论的时间相等,则按Pictures.created排序。

还有另外一件事需要考虑。在更加填充的对象上构建查询。如果每个Picture HasMany Comments尝试在Comments上构建您的查询。在Pictures上构建查询时,我不知道如何对结果进行排序。因为检索到的记录不是按Pictures.id排序,而是当结果转换为对象模型时,注释嵌套在图片中,之前的排序会被处理掉。

最后不要让事情复杂化。在查询中使用php逻辑不会提高性能,否则会降低代码的可读性。因此,如果您要执行php逻辑,请首先检索所有数据,然后使用几个简单的foreach来处理它。