CakePHP 4 如何合并关联表,使用Union合并关联表并添加查询条件?
UNION合并关联表带条件分页实现方案
完全可以使用UNION合并多个关联表的查询结果,同时为各表附加独立查询条件,再配合分页统一输出,基于你使用的CakePHP查询构造器,实现方式如下:
核心前提
所有参与UNION的子查询必须满足:字段数量一致、字段类型匹配、字段顺序完全相同,否则会出现查询报错或数据错乱的问题。
实现代码
1. 构造各子查询(可独立加关联、条件)
// 子查询1:查询符合条件的Posts数据 $postsQuery = $this->Posts->find() ->select([ 'id', 'content', 'user_id', 'created', 'source_type' => "'post'" // 自定义字段标记数据来源 ]) ->contain(['Users', 'Likes']) // 独立加载所需关联 ->where([ 'Posts.status' => 1, // Posts专属查询条件 'Posts.created >=' => new \DateTime('-30 days') ]); // 子查询2:查询符合条件的Comment数据 $commentsQuery = $this->Comment->find() ->select([ 'id', 'content', 'user_id', 'created', 'source_type' => "'comment'" // 和第一个子查询的字段完全对齐 ]) ->contain(['Users', 'Likes']) // 独立加载所需关联 ->where([ 'Comment.is_public' => 1, // Comment专属查询条件 'Comment.created >=' => new \DateTime('-30 days') ]);
2. 合并查询并分页
// 合并两个子查询,unionAll保留重复数据,union自动去重按需选择 $mergedQuery = $postsQuery->unionAll($commentsQuery); // 给合并后的总结果加排序规则 $mergedQuery->order(['created' => 'DESC']); // 配置分页参数,直接传入合并后的查询实例分页 $this->paginate = [ 'limit' => 15, ]; $results = $this->paginate($mergedQuery);
注意事项
- 所有子查询的
select定义必须严格对齐,字段数量、类型、顺序都要保持一致 - 自定义
source_type字段可以方便你在渲染数据时区分不同来源的内容,做差异化展示 - 各子查询可以独立配置
contain加载所需关联,也可以给关联单独加查询条件,互不干扰 - 如果不需要保留重复数据,把
unionAll替换为union即可,后者会自动执行去重逻辑
内容的提问来源于stack exchange,提问作者Kiruaaa
相关产品推荐
相关产品推荐

