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 相关文章推荐
详细介绍:Apache+PHP+MySQL配置攻略
Sep 05 PHP
PHP入门
Oct 09 PHP
PHP+MySQL5.0中文乱码解决方法
Nov 20 PHP
PHP和XSS跨站攻击的防范
Apr 17 PHP
php中的MVC模式运用技巧
May 03 PHP
php 短链接算法收集与分析
Dec 30 PHP
解析php入库和出库
Jun 25 PHP
php中3种方法删除字符串中间的空格
Mar 10 PHP
ThinkPHP权限认证Auth实例详解
Jul 22 PHP
codeigniter显示所有脚本执行时间的方法
Mar 21 PHP
php计算多维数组中所有值总和的方法
Jun 24 PHP
PHP getNamespaces()函数讲解
Feb 03 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
中国的第一台收音机
2021/03/01 无线电
可缩放Reloaded-一个针对可缩放元素的复用组件
2007/03/10 Javascript
jQuery 源码分析笔记(7) Queue
2011/06/19 Javascript
让checkbox不选中即将选中的checkbox不选中
2014/07/11 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
跨域请求的完美解决方法(JSONP, CORS)
2016/06/12 Javascript
javascript基础练习之翻转字符串与回文
2017/02/20 Javascript
详解react、redux、react-redux之间的关系
2018/04/11 Javascript
vue template中slot-scope/scope的使用方法
2018/09/06 Javascript
在vue中使用vue-echarts-v3的实例代码
2018/09/13 Javascript
详解node字体压缩插件font-spider的用法
2018/09/28 Javascript
详解js 创建对象的几种方法
2019/03/08 Javascript
vue router 通过路由来实现切换头部标题功能
2019/04/24 Javascript
封装微信小程序http拦截器过程解析
2019/08/13 Javascript
python 开发的三种运行模式详细介绍
2017/01/18 Python
利用Python批量提取Win10锁屏壁纸实战教程
2018/03/27 Python
在PyCharm中三步完成PyPy解释器的配置的方法
2018/10/29 Python
利用python实现对web服务器的目录探测的方法
2019/02/26 Python
Python实现一个数组除以一个数的例子
2019/07/20 Python
基于Python安装pyecharts所遇的问题及解决方法
2019/08/12 Python
python使用turtle库绘制奥运五环
2020/02/24 Python
Python爬虫requests库多种用法实例
2020/05/28 Python
Python字典fromkeys()方法使用代码实例
2020/07/20 Python
Python fileinput模块如何逐行读取多个文件
2020/10/05 Python
使用Python提取文本中含有特定字符串的方法示例
2020/12/09 Python
python 图像增强算法实现详解
2021/01/24 Python
使用HTML5和CSS3制作一个模态框的示例
2018/03/07 HTML / CSS
全球最大的户外用品零售商之一:The House
2018/06/12 全球购物
一些PHP的面试题
2015/05/06 面试题
分层教学实施方案
2014/03/19 职场文书
工厂标语大全
2014/10/06 职场文书
2014年食堂工作总结
2014/11/20 职场文书
世界卫生日宣传活动总结
2015/02/09 职场文书
初中美术教学反思
2016/02/17 职场文书
使用CSS实现一个搜索引擎的原理解析
2021/09/25 HTML / CSS
一级电子管军用接收机测评
2022/04/05 无线电