Laravel关联模型中过滤结果为空的结果集(has和with区别)
发布:smiling 来源: PHP粉丝网 添加日期:2021-10-31 20:13:50 浏览: 评论:0
这篇文章主要介绍了Laravel关联模型中过滤结果为空的结果集(has和with区别),需要的朋友可以参考下。
首先看代码:
- $userCoupons = UserCoupons::with(['coupon' => function($query) use($groupId){
- return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([
- 'group_id' => $groupId,
- ]);
- }])
- // 更多查询省略...
数据结构是三张表用户优惠券表(user_coupons)、优惠券表(coupons),商家表(corps),组优惠券表(group_coupons) (为了方便查看,后两项已去除)
这里我本意想用模型关联查出用户优惠券中属于给定组gourpId的所有数据(如果为空该条数据就不返回)。
但有些结果不是我想要的:
- array(20) {
- ["id"]=>
- int(6)
- ["user_id"]=>
- int(1)
- ["corp_id"]=>
- int(1)
- ["coupon_id"]=>
- int(4)
- ["obtain_time"]=>
- int(1539739569)
- ["receive_time"]=>
- int(1539739569)
- ["status"]=>
- int(1)
- ["expires_time"]=>
- int(1540603569)
- ["is_selling"]=>
- int(0)
- ["from_id"]=>
- int(0)
- ["sell_type"]=>
- int(0)
- ["sell_time"]=>
- int(0)
- ["sell_user_id"]=>
- int(0)
- ["is_compose"]=>
- int(0)
- ["group_cover"]=>
- string(0) ""
- ["is_delete"]=>
- int(0)
- ["score"]=>
- int(100)
- ["created_at"]=>
- NULL
- ["updated_at"]=>
- NULL
- ["coupon"]=>
- NULL // 注意返回了coupons为空的数据
- }
记录中有的coupon有记录,有的为空,想想也是,with只是用sql的in()实现的所谓预加载,无论怎样主user_coupons的数据都是会列出的。
它会有两条sql查询,第一条查主数据,第二条查关联,这里第二条sql如下:
select `id`, `group_id`, `cover`, `group_number`, `group_cover` from `youquan_coupons` where `youquan_coupons`.`id` in (1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14) and (`group_id` = 1) and `youquan_coupons`.`deleted_at` is null
如果第二条为空,主记录的关联字段就是NULL。
后来看到了Laravel关联的模型的has()方法,has()是基于存在的关联查询,下面我们用whereHas()(一样作用,只是更高级,方便写条件)
这里我们思想是把判断有没有优惠券数据也放在第一次查询逻辑中,所以才能实现筛选空记录。
加上whereHas()后的代码如下
- $userCoupons = UserCoupons::whereHas('coupon', function($query) use($groupId){
- return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([
- 'group_id' => $groupId,
- ]);
- })->with(['coupon' => function($query) use($groupId){
- return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover');
- }])-> // ...
看下最终的SQL:
- select * from `youquan_user_coupons` where exists (select `id`, `group_id`, `cover`, `group_number`, `group_cover` from `youquan_coupons` where `youquan_user_coupons`.`coupon_id` = `youquan_coupons`.`id` and (`group_ids` = 1) and `youquan_coupons`.`deleted_at` is null) and (`status` = 1 and `user_id` = 1)
这里实际上是用exists()筛选存在的记录,然后走下一步的with()查询,因为此时都筛选一遍了,所以with可以去掉条件。
显然区分这两个的作用很重要,尤其是在列表中,不用特意去筛选为空的数据,而且好做分页。
Tags: Laravel关联模型 has with
- 上一篇:多个Laravel项目如何共用migrations详解
- 下一篇:最后一页
相关文章
- ·Yii框架关联查询with用法分析(2021-05-01)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)