如图,一个服务(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. springboot2.0 springcloud 断路器仪表盘支持

    springboot 1.5 的时候  springcloud 添加 断路器仪表盘  按照网上的方法是没有问题的  但是 springboot2.0的时候一直无法连接 所以需要添加 @Beanpubl ...

  2. 【C++】const & 指针

    https://blog.csdn.net/qq_21808961/article/details/78401950

  3. 安装.net 服务时出现0x80131515错误的解决办法

    使用InstallUtil.exe安装一个用.NET写的Windows服务时,报错了,错误信息如下: Exception occurred while initializing the install ...

  4. php_screw安装,使用

    安装步骤:1. 下载源码:wget http://nchc.dl.sourceforge.net/project/php-screw/php-screw/1.5/php_screw-1.5.tar.g ...

  5. ARC085E MUL

    https://atcoder.jp/contests/arc085/tasks/arc085_c 题目大意 略 解法 最小割即可. 直接建图有负边,但是因为我们知道最后在割上的边数一定为 \(N\) ...

  6. [转][ActiveMQ]Apache.NMS.ActiveMQ 用法

    下载 C# 组件:http://archive.apache.org/dist/activemq/apache-nms/1.7.0/ 使用说明:https://www.cnblogs.com/cjm1 ...

  7. vscode中使用beautify插件格式化vue文件

    1.点击设置,找到beautify.language并在html一栏里加上vue "beautify.language": { "js": { "ty ...

  8. vue 路由别名 路由跳转

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 游戏中的沉浸(Flow in Games)

    转自:https://www.jianshu.com/p/4c52067f6594 作者:陈星汉(JenovaChen) 本论文的主旨在于提供一种独特的方法论,用以指导游戏设计中的以玩家为中心的动态难 ...

  10. java 通过jmx获取active mq队列消息

    一.修改active mq配置文件 修改\conf\activemq.xml,带下划线部分 <!-- Licensed to the Apache Software Foundation (AS ...