当前位置: 首页 > 编程笔记 >

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

凤伟泽
2023-03-14
本文向大家介绍Laravel关联模型中过滤结果为空的结果集(has和with区别),包括了Laravel关联模型中过滤结果为空的结果集(has和with区别)的使用技巧和注意事项,需要的朋友参考一下

首先看代码:

$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区别),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!

 类似资料:
  • 问题内容: 我有两个表之间的父/子关系,以及我的Java类中的对应映射。这些表大致如下所示: 和Java代码: 这可以正常工作,但是我想在从子表中检索的行上添加一个过滤器。生成的查询如下所示: 我希望它是: 附加过滤器将只是列名和硬编码值。有没有一种方法可以使用hibernate注释? 我已经看过了,但是我总是必须从父表中引用一个列名(在JoinFormula 的属性中)。 在此先感谢您的任何建议

  • 6.4.1.SetIDRange (设置查询ID范围) 原型:function SetIDRange ( $min, $max ) 设置接受的文档ID范围。参数必须是整数。默认是0和0,意思是不限制范围。 此调用执行后,只有ID在$min和$max(包括$min和$max)之间的文档会被匹配。 6.4.2.SetFilter (设置属性过滤) 原型:function SetFilter ( $at

  • 问题内容: 我希望将空结果集的总计设置为0。我尝试了以下方法: 结果: 子问题:上面的工作在Oracle中行不通吗? 问题答案: 在有关聚合函数的文档页面中: 应该注意的是,除了这些函数, 当没有选择任何行时 ,这些函数将 返回空值 。特别是,没有行返回空值,而不是预期的零值。必要时,该函数可用于将零替换为null。 所以,如果你想保证返回的值,适用于 结果 的,而不是它的参数: 至于Oracle

  • 主要内容:分发结果类型:,FreeMaker结果类型:,重定向结果类型:正如前面提到的,<results>标签在Struts2的MVC框架的视图中所扮演的角色。动作是负责执行业务逻辑。执行业务逻辑后,接下来的步骤是使用<results>标签显示的视图。  经常有一些附带导航规则的结果。例如,如果在操作方法是对用户进行验证,有三种可能的结果。 (一)成功登录;(二)不成功的登录,用户名或密码错误;(三)帐户锁定。 在这种情况下的动作方法将被配置呈现的结果有三种可能的结果

  • 在这个oracle java教程中,它说: TYPE_FORWARD_ONLY:结果集不能滚动;其光标仅向前移动,从第一行之前移动到最后一行之后。结果集中包含的行取决于基础数据库如何生成结果。也就是说,它包含在执行查询时或在检索行时满足查询的行。 “结果集中包含的行取决于基础数据库生成结果的方式。 查询执行时间和行检索时间有什么区别?我如何知道我的数据库支持哪些?提前致谢。

  • 问题内容: 我有一个叫做 School 的模型,它有很多 学生 。 这是我模型中的代码: 我在控制器中使用此代码让所有学生: 并在视图中: 现在,我想按表中的某些字段对 学生 进行排序。我怎样才能做到这一点? 问题答案: 您可以通过几种方法实现这一目标: