记一次laravel远程关联查询

如图,一个服务(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远程关联查询的更多相关文章
- Laravel 在 with 查询中只查询个别字段
在使用 Laravel 的关联查询中,我们经常使用 with 方法来避免 N+1 查询,但是 with 会将目标关联的所有字段全部查询出来,对于有强迫症的我们来说,当然是不允许的. 这时候我们可以使用 ...
- laravel 中with关联查询限定查询字段
学习了下laravel5.6框架,果然很优雅,比如ActiveJieSuan model中作如下关联:(laravel模型关联关系可以查看https://laravelacademy.org/post ...
- 完爆Facebook/GraphQL,APIJSON全方位对比解析(三)-表关联查询
相关阅读: 完爆Facebook/GraphQL,APIJSON全方位对比解析(一)-基础功能 完爆Facebook/GraphQL,APIJSON全方位对比解析(二)-权限控制 自APIJSON发布 ...
- JAVA-Unit03: SQL(基础查询) 、 SQL(关联查询)
Unit03: SQL(基础查询) . SQL(关联查询) 列别名 当SELECT子句中查询的列是一个函数 或者表达式时,那么查询出来的结果集 中对应的该字段的名字就是这个函数或者 表达式的名字.为此 ...
- JDBC MySQL 多表关联查询查询
public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...
- MYSQL基础操作之数据约束与关联查询
一.MYSQL约束 1.默认值约束,当字段没有插入值的时候,mysql自动给该字段分配默认值. 默认值的字段允许为空. 对默认值字段也可以插入null. CREATE TABLE STUDENT( I ...
- C#代码中实现两个表(DataTable)的关联查询(JOIN)
之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个表中的数据已经取到代码中,需要在代码中将这两个表关联起来,并得到它们横 ...
- Mybatis关联查询和数据库不一致问题分析与解决
Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...
- Mysql多表表关联查询 inner Join left join right join
Mysql多表表关联查询 inner Join left join right join
随机推荐
- 在经过身份验证的服务中不支持跨域 javascript 回调
在 asp.net web forms 站点中做了一个 wcf restful service 接口,开启了webforms 身份认证. 当 webforms 站点用户登录之后,访问 restful ...
- Git从库中移除已删除大文件
写在前面大家一定遇到过在使用Git时,不小心将一个很大的文件添加到库中,即使删除,记录中还是保存了这个文件.以后不管是拷贝,还是push/pull都比较麻烦.今天在上传工程到github上,发现最大只 ...
- JRockit检测Tomcat内存溢出JAVA内存泄漏问题
http://blog.csdn.net/liyanhui1001/article/details/8240473 公司的一个Java应用系统上线以来,基本每1天OutOfMemoryError: P ...
- Python中的@符号
1.基本含义 @符号用做函数的修饰符,可以在模块或者类的定义层内对函数进行修饰,出现在函数定义的前一行,不允许和函数定义在同一行. 一个修饰符就是一个函数,它将被修饰的函数作为参数,并返回修饰后的同名 ...
- Linux下mysql的root密码修改方法(ERROR 1054)
#1.停止mysql数据库 /etc/init.d/mysqld stop #2.执行如下命令 mysqld_safe --user=mysql --skip-grant-tables --skip- ...
- DLL简单分析与调用方法
最近为了分析一个没有代码的DLL有哪些函数,找了各种方法. 把结果分享一下:三个方法都没法得到函数的参数,有点让我失望. DLL Export Viewer NikPEViewer Dumpbin 配 ...
- navicat for mysql 注册码,简简单单,一个搞定(蔡军帅亲测有效)
打开navicat for mysql接着打开帮助,选中注册, 把下面的复制上去就可以了 NAVH-WK6A-DMVK-DKW3 转载自:https://blog.csdn.net/qq_403845 ...
- 浏览器渲染页面的时候,不同的script块之间的关系
浏览器渲染页面时,当读到script元素的时候,浏览器中的js引擎会分多个script代码块来读取,不同的script代码出错互不影响,但是由于script中的变量作用域是全局,所以前面代码块声明的变 ...
- word 添加文本框
转https://blog.csdn.net/sroco/article/details/17044973 如何在word2013(2007.2010)中添加带滚动条的文本框 2013年11月30日 ...
- 再说项目 Dec 27th 2018
其实对于任何项目来说,最难不是开发或者系统等技术的问题,反而是需求的问题,需求一直变,一直定不下来,导致流程变来变去,系统方案层面也确定不下来.而需求的问题,归根结底还是人的问题.项目的关键用户对现有 ...