Php 拉威尔在哪里有许多精确的匹配

Php 拉威尔在哪里有许多精确的匹配,php,laravel,postgresql,eloquent,query-builder,Php,Laravel,Postgresql,Eloquent,Query Builder,我有一个模型与多个关系: 尝试在没有where的情况下使用此选项 Product::with(array('categories' => function($q) use ($categories){ $query->whereIn('name', $categories); }))->get(); 根据您的要求,您的MySQL查询如下: 使用LEFT JOIN获取产品的映射类别的总数 在产品上使用分组依据,比较其总映射类别与基于用户输入的匹配类别 可以使用HAVI

我有一个
模型
多个
关系:


尝试在没有where的情况下使用此选项

Product::with(array('categories' => function($q) use ($categories){
    $query->whereIn('name', $categories);
}))->get();

根据您的要求,您的MySQL查询如下:

  • 使用
    LEFT JOIN
    获取产品的映射
    类别的总数
  • 在产品上使用
    分组依据
    ,比较其
    总映射类别
    与基于用户输入的匹配类别
  • 可以使用
    HAVING
    子句进行上述比较,其中
    映射的类别总数应等于用户提供的类别计数。相同的
    根据用户输入匹配类别
    也应与用户提供的类别的准确计数匹配
  • 查询生成器可以通过以下方式实现这一点:

    $arrCategory    =   ['category1', 'category2'];
    $strCategory    =   "'" . implode("','", $arrCategory) . "'";
    $intLength      =   count($arrCategory);
    
    $products       =   Product::leftJOin('product_category', 'products.id', '=', 'product_category.product_id')
                            ->leftJoin('categories', function ($join) use ($arrCategory) {
                                $join->on('categories.id', '=', 'product_category.category_id')
                                    ->whereIn('categories.name', $arrCategory);
                            })
                            ->groupBy('products.id')
                            ->havingRaw("COUNT(0) = $intLength AND SUM(IF(categories.name IN ($strCategory), 1, 0)) = $intLength")
                            ->select(['products.id'])
                            ->get();
    dd($products);
    

    注意:如果您在MySQL中启用了
    only\u full\u groupby
    模式,那么在
    groupby
    select
    子句中都包含您想要获取的products表列。

    谢谢您的回答,我用:of sub-select和,运算符(包含于)解决了这个问题:

    $categories=['category1','category2'];
    产品::whereExists(功能($q)使用($categories){
    $q->fromSub(函数($query){
    $query->selectRaw(“数组\u agg(categories.name)作为categoriesArr”)
    ->来自('类别')
    ->join('product\u category'、'categories.id'、'='、'product\u category.category\u id'))
    ->whereRaw('products.id=product_category.product_id');
    
    },'foo')->whereRaw(“分类”为什么不
    其中(“名称”,$categories)
    ?不需要循环。@TimLewis,这就是问题所在,
    其中
    返回所有产品,如果它找到至少一个匹配项,我需要精确匹配,如果我的数组包含
    category1
    ,我不想获取包含
    category1,category2
    ,只包含
    category1
    ,而不包含任何其他内容的产品r category在SQL中甚至不可行,至少不能直接…如果您想排除结果,您可以不在中使用,但您需要提前知道排除的值,嗯,我想我会这样做。在我的脑海中,一个
    $categories
    的长度计数与使用
    where()返回的
    categories
    交叉引用
    应该可以工作,但我不确定您将如何编写该代码。@TimLewis,在laravel中,您可以传递一个
    第三个
    参数来比较计数,更新了我的问题。感谢您的回答:will check,我已经更新了我的问题,(注意:我使用的是PostgreSQL)我不知道postgresSQL,但如果您可以构建查询,请尝试相同的逻辑。应该可以工作。
    $arrCategory    =   ['category1', 'category2'];
    $strCategory    =   "'" . implode("','", $arrCategory) . "'";
    $intLength      =   count($arrCategory);
    
    $products       =   Product::leftJOin('product_category', 'products.id', '=', 'product_category.product_id')
                            ->leftJoin('categories', function ($join) use ($arrCategory) {
                                $join->on('categories.id', '=', 'product_category.category_id')
                                    ->whereIn('categories.name', $arrCategory);
                            })
                            ->groupBy('products.id')
                            ->havingRaw("COUNT(0) = $intLength AND SUM(IF(categories.name IN ($strCategory), 1, 0)) = $intLength")
                            ->select(['products.id'])
                            ->get();
    dd($products);