目前我正在尝试实现时间轴功能,该功能需要在两个相关表中对创建的列进行排序,并相应地更新父表(在我的案例中为图片)。
更具体地说,我有一张有很多评论的图片表。我想根据评论和图片表的创建列中的最新时间戳对图片进行排序。
我有以下查询,它检索必要的数据,但没有正确排序:
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语句,但我能找到的关于该选项的所有信息都是它可以用于不相关的表,而不是相关的。
任何人都可以就如何解决这个问题给我一些指示?
答案 0 :(得分:0)
首先,你的目的应该是明确的。哪种订购优先考虑? Pictures.created
或Comments.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
来处理它。