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);