提取具有所有特定关系的记录

时间:2019-01-18 00:12:04

标签: sql laravel join many-to-many relationship

我有下一个模式:

nutrients
|id|label        |type
|1 |Avocado      |fats
|2 |Cooked shrimp|proteins
|3 |Raw oatmeal  |carbohydrates
|4 |Chocolate    |fats

recipes
|id|label
|1 |Something with Avocado
|2 |Something w Avocado, chocolate and raw oatmeal

nutrient_recipe
|nutrient_id|recipe_id
|1          |1
|1          |2
|3          |2
|4          |2

我只想获取营养成分完全相同的食谱。 例如:

  1. 我想要一个只有脂肪的食谱。

它应该返回鳄梨(id:1)


  1. 我想要一个只有脂肪和碳水化合物的食谱。

它应该返回牛油果,巧克力和生燕麦片(id:2)

我该如何实现?

我正在与 Laravel 合作,如果您利用口才的话,那就太好了。

编辑:

感谢@GordonLinoff

我可以实现下一个代码:

App\Models\Recipe::whereHas('nutrients', function ($query) {
    $query->havingRaw("sum(case when nutrients.type = 'fats' then 1 else 0 end) > 0")
        ->havingRaw("sum(case when nutrients.type not in ('fats') then 1 else 0 end) = 0")
        ->groupBy('recipes.id')
        ->select('recipes.id');
})

很明显,此代码缝属于过滤搜索,所以我希望这对某人有帮助。

2 个答案:

答案 0 :(得分:2)

您可以使用group byhaving。这是“脂肪”的示例:

select nr.recipe_id
from nutrient_recipe nr join
     nutrients n
     on nr.nutrient_id = n.id
group by nr.recipe_id
having sum(case when n.type = 'fats' then 1 else 0 end) > 0 and
       sum(case when n.type not in ('fats') then 1 else 0 end) = 0 ;

第一个having条件表明至少有一种营养物质是“脂肪”。第二个说没有。

您可以使用更多having子句轻松地扩展它:

select nr.recipe_id
from nutrient_recipe nr join
     nutrients n
     on nr.nutrient_id = n.id
group by nr.recipe_id
having sum(case when n.type = 'fats' then 1 else 0 end) > 0 and
       sum(case when n.type = 'carbohydrates' then 1 else 0 end) > 0 and
       sum(case when n.type not in ('fats', 'carbohydrates') then 1 else 0 end) = 0 ;

答案 1 :(得分:0)

$get = nutrients::whereIn('type', ['type one', 'type two'])->get();

然后将其保存在另一个表中。