记一次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
随机推荐
- java基础(三):反射、反序列化破解单列模式和解决方式
单例模式指的是一个类只有一个对象,通过一些措施达到达到这个目的.但是反射和反序列化可以获得多个不同的对象. 先简单的认识一下单例模式 一:单例模式 通过私有构造器,声明一个该类的静态对象成员,提供一个 ...
- Python3 多线程例子
import threading, zipfile class AsyncZip(threading.Thread): def __init__(self, infile, outfile): thr ...
- IMPALA部署和架构(一)
IMPALA部署和架构(一) 一,概要 因公司业务需求,需要一个查询引擎满足快速查询TB级别的数据,所以我们找到了presto和impala,presto在前面讲过今天只说impala,impala ...
- rsync命令简单用法介绍
rsync有两种常用的认证方式,一种为rsync-daemon方式,另外一种则是ssh.在一些场合,使用rsync-daemon方式会比较缺乏灵活性,ssh方式则成为首选.但是今天实际操作的时候发现当 ...
- 第6章 Hyperledger Fabric模型
This section outlines the key design features woven into Hyperledger Fabric that fulfill its promise ...
- C# CRC - 16
using System; static class Program { static void Main() { string input = "8000"; var bytes ...
- 通过localhost访问和通过IP地址访问页面CSS样式不一样
在开发ICT项目管理系统时,发现在开发环境下看到的页面和在部署环境下看到的页面不一样.开发环境下看到的页面比较舒服,部署后看到的页面比较生涩.究其原因,发现地址栏里面一个是localhost,一个是I ...
- C# Winform 中使用FTP实现软件自动更新功能
实现思路:通过访问FTP站点,将站点中的文件下载至软件指定位置. 第一步:FTP站点中导入需要下载更新的程序文件,并添加配置文件(配置下载后文件的下载路径),如下图所示: 第二步:Winfrom程序读 ...
- 安装.net 服务时出现0x80131515错误的解决办法
使用InstallUtil.exe安装一个用.NET写的Windows服务时,报错了,错误信息如下: Exception occurred while initializing the install ...
- activiti中的查询sql
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...