如图,一个服务(service)对应一个用户(user),一个用户对应多个标签(tag),同时一个tag也可以通过中间表(pivot)对应对个用户。

现在业务需求如下:查service,这些service对应的user同时拥有tag1、tag2、tag3、tag4标签。

一个很容易犯的错误如下:

$tags = ['tag1', 'tag2', 'tag3', ''tag4];

$query = ServiceModel::query()

$query->whereHas('user.tags', function($query) use($tags) {
foreach($tags as $tag){
$query->where('tag_name', '=', $tag);
}
}); $query-get();

这翻译过来是:找到某service,该service有user,且user有tag,这些tag的tag_name还要满足既等于tag1又等于tag2又等于tag3还等于tag4。

很显然,查询的结果为空,因为一个tag只有一个tag_name。

那换种方式:

$tags = ['tag1', 'tag2', 'tag3', ''tag4];

$query = ServiceModel::query()

$query->whereHas('user.tags', function($query) use($tags) {
$query->whereIn('tag_name', $tags);
}); $query-get();

这样也不对,因为要同时拥有4种标签,这种写法标签间是OR的关系

翻译过来是:找到某service,该service有user,且user有tag,这些tag的tag_name只要出现在tag1、tag2、tag3、tag4中就选出来。

那如何找到某service,该service对应的user的标签既有tag1又有tag2又有tag3还有tag4呢?

其实只要把foreach置于外部即可:

$tags = ['tag1', 'tag2', 'tag3', ''tag4];

$query = ServiceModel::query()

foreach($tags as $tag){
$query->whereHas('user.tags', function($query) use($tag) {
$query->where('tag_name', '=', $tag);
});
} $query-get();

这样翻译过来:(第一个循环)找到某service,该service有user,且user有tag,tag为tag1 ;循环加入的条件都是AND的关系。

其实还是化繁为简的思想:

找到某service,其对应user同时拥有多个tag的查询太难了,挺绕,那先找到只拥有1个tag(如tag1)的全部service记录总可以吧:

$query = ServiceModel::query()

$query->whereHas('user.tags', function($query) use($tag) {
$query->where('tag_name', '=', 'tag1');
});

这和laravel手册上基于存在的关联查询例子几乎一样,那找到只拥有tag2的service记录,不就是把where里面的tag1换成tag2吗,同理其他tag,那这不就相当于对tag数组循环并添加whereHas条件吗...

记一次laravel远程关联查询的更多相关文章

  1. Laravel 在 with 查询中只查询个别字段

    在使用 Laravel 的关联查询中,我们经常使用 with 方法来避免 N+1 查询,但是 with 会将目标关联的所有字段全部查询出来,对于有强迫症的我们来说,当然是不允许的. 这时候我们可以使用 ...

  2. laravel 中with关联查询限定查询字段

    学习了下laravel5.6框架,果然很优雅,比如ActiveJieSuan model中作如下关联:(laravel模型关联关系可以查看https://laravelacademy.org/post ...

  3. 完爆Facebook/GraphQL,APIJSON全方位对比解析(三)-表关联查询

    相关阅读: 完爆Facebook/GraphQL,APIJSON全方位对比解析(一)-基础功能 完爆Facebook/GraphQL,APIJSON全方位对比解析(二)-权限控制 自APIJSON发布 ...

  4. JAVA-Unit03: SQL(基础查询) 、 SQL(关联查询)

    Unit03: SQL(基础查询) . SQL(关联查询) 列别名 当SELECT子句中查询的列是一个函数 或者表达式时,那么查询出来的结果集 中对应的该字段的名字就是这个函数或者 表达式的名字.为此 ...

  5. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  6. MYSQL基础操作之数据约束与关联查询

    一.MYSQL约束 1.默认值约束,当字段没有插入值的时候,mysql自动给该字段分配默认值. 默认值的字段允许为空. 对默认值字段也可以插入null. CREATE TABLE STUDENT( I ...

  7. C#代码中实现两个表(DataTable)的关联查询(JOIN)

    之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个表中的数据已经取到代码中,需要在代码中将这两个表关联起来,并得到它们横 ...

  8. Mybatis关联查询和数据库不一致问题分析与解决

    Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...

  9. Mysql多表表关联查询 inner Join left join right join

    Mysql多表表关联查询 inner Join left join right join

随机推荐

  1. 50款经典电影效果LR预设

    Film Looks LR Presets是一套非常专业的经典电影效果LR预设,包含50个不同效果的Lightroom预设,由专业摄影师和Lightroom专家开发,此套LR预设模拟摄影时代的经典电影 ...

  2. 网络工具之chisel + openvpn混合

    目的: 访问内网的shared folder 内网可以无缝访问internet而不需要设置代理(因为有些软件没办法支持代理,比如rustup) 解决方案: 基本思路 家里 设置chisel服务开放44 ...

  3. 剑指offer 12.代码的完整性 数值的整数次方

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.   本人渣渣代码: public double Power(double ba ...

  4. DNS缓存服务器与转发服务器

    DNS缓存服务器与转发服务器 什么是缓存服务器(cache-only) 缓存服务器只需要根区域解析库文件,不包含任何其它区域解析库文件,这样的服务器就叫着缓存服务器.这样的服务器只有缓存搜寻结果的功能 ...

  5. php商品对比功能代码分享

    商品对比调用的JS文件(包含了商品对比框浮动JS): /*浮动窗口*/ (function(){     var n=10;   var obj=document.getElementById(&qu ...

  6. 为毛GPU Cache不能移动顶点?

    这篇文章属于典型的剥洋葱文,由表及里,逐步引入新的知识点,挖掘最本质的原因.这篇文的逻辑是先假设再证明,按照这个思路去阅读会比较轻松. Maya里的GPU Cache导入的几何体为什么不能编辑顶点?这 ...

  7. Session小结

    session小结1.session是什么Session是服务器为每个访问这个服务器的客户端用户创建的一个容器.这个容器中存储的数据能够在多个request之间实现共享.而且,这个容器只属于当前这个用 ...

  8. C# Enum 获取枚举属性

    Enum使用 获取枚举属性 注意:扩展方法必须定义为静态类,静态方法中. public enum EnumPatientSource { [Description("住院")] I ...

  9. 2018总结-->2019新目标

    2018完成的事情: ①考到了驾照: ②刷了很多题,春季找到了实习,赚到了去日本旅游的经费和2019毕业租房的预算,最后签了offer: ③去了西安.天津.山西,看到了不一样的人和事: ④发了小论文, ...

  10. [转][C#]服务安装卸载命令

    c:\windows\microsoft.net\Framework\v2.0.50727\installutil.exe  [/u] X:\服务.exe