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 相关文章推荐
PHP4(windows版本)中的COM函数
Oct 09 PHP
ASP和PHP都是可以删除自身的
Apr 09 PHP
PHP 强制性文件下载功能的函数代码(任意文件格式)
May 26 PHP
基于Linux调试工具strace与gdb的常用命令总结
Jun 03 PHP
ueditor 1.2.6 使用方法说明
Jul 24 PHP
PHP实现生成透明背景的PNG缩略图函数分享
Jul 08 PHP
yii2中使用Active Record模式的方法
Jan 09 PHP
php+mysql实现的二级联动菜单效果详解
May 10 PHP
PHP巧妙利用位运算实现网站权限管理的方法
Mar 12 PHP
PHP5中使用mysqli的prepare操作数据库的介绍
Mar 18 PHP
php web环境和命令行环境下查找php.ini的位置
Jul 17 PHP
php面向对象重点知识分享
Sep 27 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
如何在PHP中使用正则表达式进行查找替换
2013/06/13 PHP
php中error与exception的区别及应用
2014/07/28 PHP
js宝典学习笔记(上)
2007/01/10 Javascript
jQuery EasyUI API 中文文档 - ProgressBar 进度条
2011/09/29 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
jQuery中append()方法用法实例
2014/12/25 Javascript
angular.element方法汇总
2015/01/07 Javascript
JavaScript中Date对象的常用方法示例
2015/10/24 Javascript
分享我的jquery实现下拉菜单心的
2015/11/29 Javascript
Bootstrap Table使用方法解析
2016/10/19 Javascript
详解js的六大数据类型
2016/12/27 Javascript
jquery滚动条插件slimScroll使用方法
2017/02/09 Javascript
jQuery插件echarts实现的去掉X轴、Y轴和网格线效果示例【附demo源码下载】
2017/03/04 Javascript
JS作用域链详解
2017/06/26 Javascript
让bootstrap的carousel支持滑动滚屏的实现代码
2017/11/27 Javascript
vue 实现复制内容到粘贴板clipboard的方法
2018/03/17 Javascript
JS实现table表格内针对某列内容进行即时搜索筛选功能
2018/05/11 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
微信小程序五子棋游戏AI实现方法【附demo源码下载】
2019/02/20 Javascript
Vue基本使用之对象提供的属性功能
2019/04/30 Javascript
js中forEach,for in,for of循环的用法示例小结
2020/03/14 Javascript
[01:00:44]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第三局
2016/03/04 DOTA
Pandas之drop_duplicates:去除重复项方法
2018/04/18 Python
Python运维之获取系统CPU信息的实现方法
2018/06/11 Python
终端命令查看TensorFlow版本号及路径的方法
2018/06/13 Python
Python OpenCV调用摄像头检测人脸并截图
2020/08/20 Python
Python3 合并二叉树的实现
2019/09/30 Python
python通过实例讲解反射机制
2019/10/17 Python
python3 deque 双向队列创建与使用方法分析
2020/03/24 Python
python批量处理多DNS多域名的nslookup解析实现
2020/06/28 Python
Python 实现将某一列设置为str类型
2020/07/14 Python
python设置中文界面实例方法
2020/10/27 Python
internal修饰符起什么作用
2013/12/16 面试题
电工实训报告总结
2014/11/05 职场文书
2014年初级职称工作总结
2014/12/08 职场文书
社区元宵节活动总结
2015/02/06 职场文书