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 相关文章推荐
使用VisualStudio开发php的图文设置方法
Aug 21 PHP
基于php验证码函数的使用示例
May 03 PHP
ThinkPHP 表单自动验证运用示例
Oct 13 PHP
php实现插入数组但不影响原有顺序的方法
Mar 27 PHP
php正则替换处理HTML页面的方法
Jun 17 PHP
PHP获取某个月最大天数(最后一天)的方法
Jul 29 PHP
分享php邮件管理器源码
Jan 06 PHP
Symfony实现行为和模板中取得request参数的方法
Mar 17 PHP
PHP实现页面静态化的超简单方法
Sep 06 PHP
Yii2 批量插入、更新数据实例
Mar 15 PHP
PHP开发之用微信远程遥控服务器
Jan 25 PHP
php文件上传原理与实现方法详解
Dec 20 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 登录完成后如何跳转上一访问页面
2014/01/14 PHP
php的sprintf函数的用法 控制浮点数格式
2014/02/14 PHP
THINKPHP2.0到3.0有哪些改进之处
2015/01/04 PHP
通过判断JavaScript的版本实现执行不同的代码
2010/05/11 Javascript
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
js为空或不是对象问题的快速解决方法
2013/12/11 Javascript
深入分析jquery解析json数据
2014/12/09 Javascript
js实现文字无缝向上滚动
2017/02/16 Javascript
原生JS实现垂直手风琴效果
2017/02/19 Javascript
js a标签点击事件
2017/03/30 Javascript
JS简单验证上传文件类型的方法
2017/04/17 Javascript
vue组件之间的数据传递方法详解
2019/04/19 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
神经网络python源码分享
2017/12/15 Python
python看某个模块的版本方法
2018/10/16 Python
详解pandas删除缺失数据(pd.dropna()方法)
2019/06/25 Python
简单了解python的break、continue、pass
2019/07/08 Python
关于Python内存分配时的小秘密分享
2019/09/05 Python
python使用Thread的setDaemon启动后台线程教程
2020/04/25 Python
python 基于wx实现音乐播放
2020/11/24 Python
一个非常简单好用的Python图形界面库(PysimpleGUI)
2020/12/28 Python
HTML5 Canvas渐进填充与透明实现图像的Mask效果
2013/07/11 HTML / CSS
Bally巴利英国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/05/07 全球购物
Ado与Ado.net的相同与不同
2014/12/08 面试题
买房子个人收入证明
2014/01/16 职场文书
高中毕业自我评价
2014/02/08 职场文书
安全协议书范本
2014/04/21 职场文书
五水共治一句话承诺
2014/05/30 职场文书
植树节口号
2014/06/21 职场文书
四风对照检查剖析材料
2014/10/07 职场文书
财务会计实训报告
2014/11/05 职场文书
检讨书格式范文
2015/05/07 职场文书
离婚答辩状怎么写
2015/05/22 职场文书
Python答题卡识别并给出分数的实现代码
2021/06/22 Python
CSS 实现角标效果的完整代码
2022/06/28 HTML / CSS
Linux中sftp常用命令整理
2022/06/28 Servers