Php 基于同一列上具有多个条件的多对多关系的搜索

Php 基于同一列上具有多个条件的多对多关系的搜索,php,mysql,laravel,eloquent,laravel-5.3,Php,Mysql,Laravel,Eloquent,Laravel 5.3,我对我的laravel 5.3项目有多对多关系。 有两种模型与此问题相关。它们是作业和标记。 模型作业可以有许多与其关联的标记,模型标记也可以与许多作业相关。 在两个模型类中,我都使用关键字“belongtomany”指定了关系Many To Many。 该关系的数据库为: 表:就业 表:标签 以及透视表:作业标签 用户可以传递多个标记名以检索与用户传递的两个标记相关的作业。(和条件) 示例:当用户传递标记_name“php”和“html”时,我想显示作业[id:1 title:develope

我对我的laravel 5.3项目有多对多关系。 有两种模型与此问题相关。它们是作业标记。 模型作业可以有许多与其关联的标记,模型标记也可以与许多作业相关。 在两个模型类中,我都使用关键字“belongtomany”指定了关系Many To Many。 该关系的数据库为: 表:就业

表:标签

以及透视表
:作业标签

用户可以传递多个标记名以检索与用户传递的两个标记相关的作业。(条件)

示例:当用户传递标记_name“php”和“html”时,我想显示作业[id:1 title:developer]和[id:2 title:designer]的详细信息

提示:检索标记为“php”和“html”的作业记录

注意:用户传递的标记名的数量没有定义,即用户可以传递尽可能多的标记名


以下是我尝试过的一些东西:

$jobs = Job::whereHas('tags', function ($query) use($params) {
                    foreach ($params['tags'] as $tag) {
                        $query->where('tag', $tag);
                    }
                });
上述代码不返回任何内容,而是生成以下sql:

select * from `jobs` where exists (select * from `tags` inner join `job_tag` on `tags`.`id` = `job_tag`.`tag_id` where `job_tag`.`job_id` = `jobs`.`id` and (`tag` = css) and (`tag` = javascript))
我试图基于此sql获取结果,但结果不起作用

希望你们理解我的问题,并帮助我找到解决办法。
提前感谢。

在您的foreach中,您需要将标签与
进行比较,而不是与
进行比较

$jobs = Job::whereHas('tags', function ($query) use ($params) {
    $query->where(function ($query2) use ($params) {
        foreach ($params['tags'] as $tag) {
            $query->orWhere('tag', $tag);
        }
    })
});

我不确定是否需要第二级闭包,但如果您在事实发生后在查询中添加任何其他
WHERE
条件,它会有所帮助。

一个选项是使用多个
WHERE has
作为:

$query = Job::query();

foreach ($params['tags'] as $tag) {
    $query->whereHas('tags', function ($q) use($tag) {
        $q->where('tag', $tag);
    });
}

$jobs = $query->get();
$tag_ids = [2, 4];

假设您有一个标记
id
as的数组:

$query = Job::query();

foreach ($params['tags'] as $tag) {
    $query->whereHas('tags', function ($q) use($tag) {
        $q->where('tag', $tag);
    });
}

$jobs = $query->get();
$tag_ids = [2, 4];
然后您可以尝试以下方式:

Job::whereHas('tags', function($q) use($tag_ids) {
        $q->whereIn('tag_id', $tag_ids)
          ->groupBy('job_id')
          ->havingRaw('COUNT(DISTINCT tag_id) = '.count($tag_ids));
    })->get();

第一种选择效果很好。它生成如下查询:-
select*from'jobs'where exists(select*from'tags'内部连接'tags'。'id'='job\u tag'。'tag id'where'job\u tag'。'job\u id'='jobs'。'id'和'tag'='php)并存在(从“标签”上的“标签”内部连接“作业标签”。“id”=“作业标签”。“标签id”中的“作业标签”。“作业id”=“作业”。“id”和“标签”=“html”)
。\u谢谢你\u代码生成错误:
意外”
如果
$query->where(函数($query2)使用($params){
被删除,然后列出所有“作业”,而不是与标记相关的搜索。
Job::whereHas('tags', function($q) use($tag_ids) {
        $q->whereIn('tag_id', $tag_ids)
          ->groupBy('job_id')
          ->havingRaw('COUNT(DISTINCT tag_id) = '.count($tag_ids));
    })->get();