https://www.bbsmax.com/A/Vx5MN9GadN/
1.个人之前博文:
2.withJoin的特性
2.1 第一个特性
的博文中,阐述了利用withJoin进行关联查询的情况。这里补充一个命名特性(经过调试确认)
即关系命名的,必须与模型名保持一致,否则withJoin无法使用。(当这个不满足时,with仍可使用。大家可以调试确认)
即关系名中的School和Xueqi等必须与关联模型一致,才能使用withJoin。
2.12第二个特性
withJoin的关联查询,只支持单层关联,不支持多层。
比如:
- ->withJoin(
- [
- ‘canxunDanweiSchool’ => function($query){
- $query
- ->withJoin([‘dwJibie’,‘xiaojieShangJiDanwei’])
- ;
- },
- ‘canxunpeiyangjihuaXueqi’ => function($query) use($src){
- $query
- ->withJoin([‘glCategory’,‘pyCategory’,‘xnCategory’])
- ;
- },
- ]
)
这里可能想表达,”多层关联,即先关联到School表,再从school表中多层关联到Category表。类似的,先关联到Xueqi,再关联到Category表。“
注意,此时,使用如下代码进行单层关联查询,是可行的。
- ->when(count($src[‘canxunPeiyangjihua_pyCategory’]) > 0, function($query) use($src){
- $query->where(‘canxunpeiyangjihuaXueqi.peiyang_category_id’, ‘in’, $src[‘canxunPeiyangjihua_pyCategory’]);
})
但是,无法返回多层关联数据,即withJoin无法返回二层关联的glCategory、dwJibie等关系中的任何数据。
返回多层关联数据,只能用with,而不能用withJoin。详见博文:
TP6中实现多层关联,第一个表关联第二个表查询出的数据,再关联第三个表
3.with的特性
虽然前述博文中,with能够查询出多层的数据,但是with不支持类似于withJoin的inner Join查询(关于inner Join查询概念,请搜索网络)。即如果将博文
中的withJoin换成with,是无法实现withJoin功能的。
即使在with的代码中,添加where,那么只能实现的是关联表中的数据过滤,而不涉及本表,即不能实现join的功能。比如,如下代码:
- ->with(
- [
- ‘canxunDanweiSchool’ => function($query){
- $query
- ->with([‘dwJibie’,‘xiaojieShangJiDanwei’])
- // ->field(‘id, title, jiancheng’)//如果通过field设置输出字段,会限制关联查询dwJibie
- // ->withField(‘dwJibie’)
- ;
- },
- ‘canxunpeiyangjihuaXueqi’ => function($query) use($src){
- $query
- ->with([‘glCategory’,‘pyCategory’,‘xnCategory’])
- // ->when(count($src[‘canxunPeiyangjihua_pyCategory’]) > 0, function($query) use($src){
- // $query->where(‘peiyang_category_id’, ‘in’, $src[‘canxunPeiyangjihua_pyCategory’]);
- //// ->field(‘id, title, jiancheng’)//如果通过field设置输出字段,会限制关联查询dwJibie
- //// ->withField(‘dwJibie’)
- // })
- ;
- },
- ]
- )
其中在关系中添加的where查询,只会使得关联表中的数据进行过滤,不会对本表查询的数据进行where过滤。
比如:表a的某行数据data1,在表b中关联的某行数据,不满足where条件,那么返回的数据是,表a中的data1仍然被返回,只是表b中对应的关联数据被筛选掉。这达不到innerJoin功能
4.实现多层关联数据查询,并在关联表中实现where功能,inner join到本表。
代码如下:
- // $xxx=Db::query(‘select id from cj_canxundanwei’);
- // 整理参数
- $src = [
- ‘school_id’ => array()
- ,‘xueqi_id’ => array()
- ,‘canxunPeiyangjihua_pyCategory’=> array() //搜索培养大类
- ];
- $src = array_cover($srcfrom, $src);
- $src[‘school_id’] = strToArray($src[‘school_id’]);
- $src[‘xueqi_id’] = strToArray($src[‘xueqi_id’]);
- $src[‘canxunPeiyangjihua_pyCategory’] = strToArray($src[‘canxunPeiyangjihua_pyCategory’]);
- // 查询数据
- $data = $this
- ->with(
- [
- ‘canxunDanweiSchool’ => function($query){
- $query
- ->with([‘dwJibie’,‘xiaojieShangJiDanwei’])
- // ->field(‘id, title, jiancheng’)//如果通过field设置输出字段,会限制关联查询dwJibie
- ;
- },
- ‘canxunpeiyangjihuaXueqi’ => function($query) use($src){
- $query
- ->with([‘glCategory’,‘pyCategory’,‘xnCategory’])
- ;
- },
- ]
- )
- ->when(count($src[‘school_id’]) > 0, function($query) use($src){
- $query->where(‘school_id’, ‘in’, $src[‘school_id’]);
- })
- ->when(count($src[‘xueqi_id’]) > 0, function($query) use($src){
- $query->where(‘xueqi_id’, ‘in’, $src[‘xueqi_id’]);
- })
- ->when(count($src[‘canxunPeiyangjihua_pyCategory’]) > 0, function($query) use($src) {
- /*
- * 使用原生SQL语句
- */
- // Db::query(‘select id from cj_canxundanwei’);
- // $a='(‘;
- // foreach($src[‘canxunPeiyangjihua_pyCategory’] as $value){
- // $a=$a.(String)$value.’,’;
- // }
- // $a=substr($a,0,strlen($a)-1);
- // $a=$a.’)’;
- // $xxx=Db::query(‘select c.id from cj_canxundanwei c INNER JOIN cj_xueqi x ON c.xueqi_id = x.id where x.peiyang_category_id in ‘.$a);
- // $ddd=array();
- // foreach($xxx as $value){
- // array_push($ddd,(String)$value[‘id’]);
- // }
- // $query->where(‘id’,’in’,$ddd);
- /*
- * 使用原生SQL语句
- */
- $sch = new CX;
- $eee=$sch->withJoin([‘canxunpeiyangjihuaXueqi’=>function($query){
- $query->field(‘peiyang_category_id’);
- },])->where(“canxunpeiyangjihuaXueqi.peiyang_category_id”,‘in’, $src[‘canxunPeiyangjihua_pyCategory’])
- ->field(‘Canxundanwei.id’)->select();
- $query->where(‘id’,‘in’,$eee);
- })
- ->select();
即,只能使用原生sql语句。其中被注释”使用原生sql语句”注释掉的代码中为正确内容。而如下代码中执行的内容,返回的数据是thinkPHP的collection数据
- $sch = new CX;
- $eee=$sch->withJoin([‘canxunpeiyangjihuaXueqi’=>function($query){
- $query->field(‘peiyang_category_id’);
- },])->where(“canxunpeiyangjihuaXueqi.peiyang_category_id”,‘in’, $src[‘canxunPeiyangjihua_pyCategory’])
- ->field(‘Canxundanwei.id’)->select();
所以,
- $query->where(‘id’,‘in’,$eee);
执行会失败。
注意,db引用的是think\facade\Db类。
即,只能使用原生sql语句,实现多层关联数据查询的同时,同时再实现inner Join的功能。如有其余方法,请评论。