Laravel关联模型中过滤结果为空的结果集(has和with区别)


Posted in PHP onOctober 18, 2018

首先看代码:

$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可以去掉条件。

显然区分这两个的作用很重要,尤其是在列表中,不用特意去筛选为空的数据,而且好做分页。

总结

以上所述是小编给大家介绍的Laravel关联模型中过滤结果为空的结果集(has和with区别),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
PHP整数取余返回负数的相关解决方法
May 15 PHP
PHP四种基本排序算法示例
Apr 09 PHP
详解PHP的Yii框架中日志的相关配置及使用
Dec 08 PHP
thinkphp3.x中cookie方法的用法分析
May 19 PHP
thinkphp3.2.3 分页代码分享
Jul 28 PHP
php实现跨域提交form表单的方法【2种方法】
Oct 17 PHP
php自定义时间转换函数示例
Dec 07 PHP
php实现给二维数组中所有一维数组添加值的方法
Feb 04 PHP
YII框架批量插入数据的方法
Mar 18 PHP
php出租房数据管理及搜索页面
May 23 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
Apr 07 PHP
PHP使用glob方法遍历文件夹下所有文件的实例
Oct 17 #PHP
php 读取文件夹下所有图片、文件的实例
Oct 17 #PHP
PHP使Laravel为JSON REST API返回自定义错误的问题
Oct 16 #PHP
实现PHP中session存储及删除变量
Oct 15 #PHP
PHP实现用session来实现记录用户登陆信息
Oct 15 #PHP
PHP中使用CURL发送get/post请求上传图片批处理功能
Oct 15 #PHP
深入理解 PHP7 中全新的 zval 容器和引用计数机制
Oct 15 #PHP
You might like
Zend framework处理一个http请求的流程分析
2010/02/08 PHP
PHP判断表单复选框选中状态完整例子
2014/06/24 PHP
php cookie名使用点号(句号)会被转换
2014/10/23 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
2017/05/29 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
一个JavaScript继承的实现
2006/10/24 Javascript
JavaScript 学习笔记(四)
2009/12/31 Javascript
javascript移动设备Web开发中对touch事件的封装实例
2014/06/05 Javascript
基于jquery实现发送文章到手机的代码
2014/12/26 Javascript
js实现仿qq消息的弹出窗效果
2016/01/06 Javascript
js实现select二级联动下拉菜单
2020/04/17 Javascript
关于Javascript中document.cookie的使用
2017/03/08 Javascript
jQuery之动画ajax事件(实例讲解)
2017/07/18 jQuery
详解ES6之async+await 同步/异步方案
2017/09/19 Javascript
深入理解JS的事件绑定、事件流模型
2018/05/13 Javascript
微信公众平台获取access_token的方法步骤
2019/03/29 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
vue-dplayer 视频播放器实例代码
2019/11/08 Javascript
[02:53]2018年度DOTA2最佳战队-完美盛典
2018/12/17 DOTA
[50:50]完美世界DOTA2联赛PWL S3 Galaxy Racer vs Phoenix 第一场 12.10
2020/12/13 DOTA
python实现简单登陆系统
2018/10/18 Python
浅谈pyqt5中信号与槽的认识
2019/02/17 Python
Python3+Appium实现多台移动设备操作的方法
2019/07/05 Python
如何基于Python创建目录文件夹
2019/12/31 Python
Python多进程multiprocessing、进程池用法实例分析
2020/03/24 Python
mac安装python3后使用pip和pip3的区别说明
2020/09/01 Python
Python模拟键盘输入自动登录TGP
2020/11/27 Python
国际商务专业求职信
2014/07/15 职场文书
酒店员工辞职信范文
2015/02/28 职场文书
朋友聚会开场白
2015/06/01 职场文书
色戒观后感
2015/06/12 职场文书
给校长的建议书范文
2015/09/14 职场文书
解决Redis启动警告问题
2022/02/24 Redis
Golang数据类型和相互转换
2022/04/12 Golang