首先看代码:

$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可以去掉条件。

显然区分这两个的作用很重要,尤其是在列表中,不用特意去筛选为空的数据,而且好做分页。

本文最早发布在 Rootrl's blog

原文地址:https://segmentfault.com/a/1190000016719659

转载于:https://www.cnblogs.com/lalalagq/p/9964470.html

Laravel关联模型中过滤结果为空的结果集(has和with区别)相关推荐

  1. sequelize模型关联_使用Sequelize来计算关联模型中的行数(其中id ='x')

    我试图建立一个留言板来教自己的JavaScript.我正在与: 的NodeJS angularjs 表示 MySQL的 我有一个视图/board,它使用以下路径(和相应的sqlize查询)来获取显示& ...

  2. 六、Django ORM关联模型

    本章节将介绍ORM中的关联模型,以下测试基于book管理 一.创建关联模型 创建app01并注册 编辑全局settings.py文件,如下: INSTALLED_APPS = ['django.con ...

  3. php一对一模型关联,通过实例学习Laravel模型中的一对一关联关系

    通过实例学习Laravel模型中的一对一关联关系 一.前言 Laravel遵循[约定优于配置]的原则.PHP开发者只需要遵循Laravel框架的原则,就能减少大量的工作,这便是Laravel的魅力之一 ...

  4. 关于hibernate的关联外键生成以及外键属性列的正确插入即:解决外键插入时,在关联表中除了外键列为空,其它属性均正常级联保存

    关于hibernate的关联外键生成以及外键属性列的正确插入即:解决外键插入时,在关联表中除了外键列为空,其它属性均正常级联保存 其实解决办法十分简单: 首先确保你能够级联保存数据,当然除了关联表的外 ...

  5. Laravel Eloquent关联模型查询设置查询条件与指定字段

    我的个人博客:逐步前行STEP 1.直接获取关联模型: 1)在get中指定字段: $user->posts()->where('created_at','>',date('Y-m-d ...

  6. think php5关联模型,thinkphp5的模型中使用关联

    有以下两个表 artitcle表(表示文章) article的主键是id,外键是cateid,cateid对应于cate表的主键id. cate表(表示栏目) cate表的主键是id. 这两张表表示, ...

  7. think php5关联模型,thinkphp5中关联模型的定义与使用方法

    定义一对一关联 这里假设你已经把thinkphp5的环境都配置好了,数据库也连接OK了.想通过模型把两张表关联起来然后在通过控制器一调用就可以得到两张表的信息. 现在我准备了两张表,一张管理员表pwn ...

  8. Laravel 模型中 $hidden 的作用

    看源码的注释,$hidden 定义的属性在被 序列化 的时候会被隐藏. 文档解释:https://laravel.com/docs/5.5/eloquent-serialization#hiding- ...

  9. php基础 快速入门文档,快速入门 - Laravel 5.8 中文文档手册 - php中文网手册

    Eloquent:入门 简介 Laravel 的 Eloquent ORM 提供了一个漂亮.简洁的 ActiveRecord 实现来和数据库交互.每个数据库表都有一个对应的「模型」用来与该表交互.你可 ...

  10. laravel model 模型详细基本用法

    laravel model 模型基本用法 一.定义模型 1.命令 php artisan make:model User 如果你想要在生成模型时生成数据库迁移,可以使用--migration 或-m ...

最新文章

  1. haskell的分数运算
  2. [20170914]tnsnames.ora的管理.txt
  3. cmake通过命令行构建静态库/动态库
  4. mysql linux版本 rpm_Linux下查看MySQL版本及rpm里有没有MySQL
  5. android dns解析
  6. 【caffe-Windows】mnist实例编译之model的使用-matlab
  7. 程序语言的组成知识笔记
  8. iPhone比小米贵3000,贵在哪里?
  9. opencv30-图像矩
  10. java.math.BigDecimal cannot be cast to java.lang.Integer
  11. 使用Reaver破解开启了WPS功能的wifi密码(wpa/wpa2)
  12. 基于selenium的python浏览器脚本制作教程
  13. 惠普无线鼠标没有反应
  14. /deep/ >>> ::v-deep的用法
  15. SAP 损益类科目余额结转到未分配利润科目
  16. Python正则表达式-1
  17. python --获取内网IP地址
  18. 什么是A股、B股、H股?
  19. C++版《天空之城》
  20. 密码打马赛克已经不安全了!这款开源的去“马赛克”工具一秒还原

热门文章

  1. 毕业后半年就变成了一条“狗
  2. 如何在 Mac 上忘记 Wi-Fi 网络?
  3. 如何关闭来自苹果的个性化广告?
  4. 在 Mac App Store 上如何查看未完成的下载?
  5. HitPaw Watermark Remover for mac(视频图片去水印)
  6. 如何在Mac上将您的Apple ID更改为其他电子邮件地址?
  7. SVN Description : The working copy is locked due to a previous error.
  8. UIApplication keyWindow rootViewController 为 nil 的
  9. 9个有用的php功能
  10. beanstalkd最佳实践-编程开发