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中对用户身份认证实现两种方法
Jun 04 PHP
PHP的一个基础知识 表单提交
Jul 04 PHP
php ajax 静态分页过程形式
Sep 02 PHP
php smarty截取中文字符乱码问题?gb2312/utf-8
Nov 07 PHP
ThinkPHP CURD方法之limit方法详解
Jun 18 PHP
PHP连接sql server 2005环境配置及问题解决
Aug 08 PHP
ecshop实现smtp发送邮件
Feb 03 PHP
php实现购物车功能(下)
Jan 05 PHP
yii2分页之实现跳转到具体某页的实例代码
Jun 02 PHP
php日期操作技巧小结
Jun 25 PHP
PHP实现递归目录的5种方法
Oct 27 PHP
php模拟post提交请求调用接口示例解析
Aug 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
PHP autoload与spl_autoload自动加载机制的深入理解
2013/06/05 PHP
详解php中的implements 使用
2017/06/13 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
VBScript版代码高亮
2006/06/26 Javascript
javascript在事件监听方面的兼容性小结
2010/04/07 Javascript
Jquery ui css framework
2010/06/28 Javascript
有关DOM元素与事件的3个谜题
2010/11/11 Javascript
JS+CSS简单树形菜单实现方法
2015/09/12 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
实例分析nodejs模块xml2js解析xml过程中遇到的坑
2017/03/18 NodeJs
Vue分页组件实例代码
2017/04/17 Javascript
微信禁止下拉查看URL的处理方法
2017/09/28 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
vue2.0父子组件间传递数据的方法
2018/08/16 Javascript
async/await优雅的错误处理方法总结
2019/01/30 Javascript
微信小程序使用npm包的方法步骤
2019/08/13 Javascript
Vue实现仿iPhone悬浮球的示例代码
2020/03/13 Javascript
微信小程序中使用 async/await的方法实例分析
2020/05/06 Javascript
python函数返回多个值的示例方法
2013/12/04 Python
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
在Python中操作文件之seek()方法的使用教程
2015/05/24 Python
Python数据结构与算法之字典树实现方法示例
2017/12/13 Python
Python中创建二维数组
2018/10/17 Python
对pandas通过索引提取dataframe的行方法详解
2019/02/01 Python
python判断所输入的任意一个正整数是否为素数的两种方法
2019/06/27 Python
Python使用docx模块实现刷题功能代码
2020/02/13 Python
python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法
2020/02/26 Python
在Django中自定义filter并在template中的使用详解
2020/05/19 Python
Python3爬虫中Ajax的用法
2020/07/10 Python
Expedia印度尼西亚站:预订酒店、廉价航班和度假套餐
2018/01/31 全球购物
Wedgwood英国官方网站:英式精致骨瓷餐具、礼品与生活精品,源于1759年
2019/09/02 全球购物
怎样声明一个匿名的内部类
2016/06/01 面试题
工程师自我评价怎么写
2013/09/19 职场文书
争做文明公民倡议书
2014/08/29 职场文书
幼儿园秋季开学通知
2015/07/16 职场文书
使用compose函数优化代码提高可读性及扩展性
2022/06/16 Javascript