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 json格式和js json格式 js跨域调用实现代码
Sep 08 PHP
PHP 实现explort() 功能的详解
Jun 20 PHP
php读取3389的脚本
May 06 PHP
PHP+ajaxfileupload+jcrop插件完美实现头像上传剪裁
Jun 09 PHP
php 魔术方法详解
Nov 11 PHP
PHP中预定义的6种接口介绍
May 12 PHP
php插入含有特殊符号数据的处理方法
Nov 24 PHP
php 判断页面或图片是否经过gzip压缩的方法
Apr 05 PHP
PHP实现Unicode编码相互转换的方法示例
Nov 17 PHP
PHP设计模式之工厂模式定义与用法详解
Apr 03 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
Oct 11 PHP
php ActiveMQ的安装与使用方法图文教程
Feb 23 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的面试题集,附我的答案和分析(一)
2006/11/19 PHP
深入解析phpCB批量转换的代码示例
2013/06/27 PHP
php命令行(cli)模式下报require 加载路径错误的解决方法
2015/11/23 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
很可爱的输入框
2008/08/03 Javascript
html中table数据排序的js代码
2011/08/09 Javascript
使用javascript:将其它类型值转换成布尔类型值的解决方法详解
2013/05/07 Javascript
jquery事件与函数的使用介绍
2013/09/29 Javascript
javascript事件冒泡实例分析
2015/05/13 Javascript
省市区三级联动下拉框菜单javascript版
2015/08/11 Javascript
JavaScript为事件句柄绑定监听函数实例详解
2015/12/15 Javascript
BootStrap Validator使用注意事项(必看篇)
2016/09/28 Javascript
WEB开发之注册页面验证码倒计时代码的实现
2016/12/15 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
javascript 作用于作用域链的详解
2017/09/27 Javascript
JS实现的缓冲运动效果示例
2018/04/30 Javascript
js使用文档就绪函数动态改变页面内容示例【innerHTML、innerText】
2019/11/07 Javascript
快速解决element的autofocus失效问题
2020/09/08 Javascript
Python的内存泄漏及gc模块的使用分析
2014/07/16 Python
基于Python的XSS测试工具XSStrike使用方法
2017/07/29 Python
Python 多进程并发操作中进程池Pool的实例
2017/11/01 Python
python面试题Python2.x和Python3.x的区别
2019/05/28 Python
python中pathlib模块的基本用法与总结
2020/08/17 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
Prototype如何实现页面局部定时刷新
2013/08/06 面试题
J2EE模式面试题
2016/10/11 面试题
社区巾帼文明岗事迹材料
2014/06/03 职场文书
医院保洁服务方案
2014/06/11 职场文书
地震捐款倡议书
2014/08/29 职场文书
2014年学校体育工作总结
2014/12/08 职场文书
2015年化妆品销售工作总结
2015/05/11 职场文书
个人工作总结怎么写?
2019/04/09 职场文书
如何搭建 MySQL 高可用高性能集群
2021/06/21 MySQL
Spring中的使用@Async异步调用方法
2021/11/01 Java/Android
CentOS8.4安装Redis6.2.6的详细过程
2021/11/20 Redis
Redis实战之Lettuce的使用技巧详解
2022/12/24 Redis