【问题标题】:Fetch records that has all specific relationships获取具有所有特定关系的记录
【发布时间】:2019-06-12 06:04:01
【问题描述】:

我有下一个架构:

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. 我想要一份只有脂肪的食谱。

它应该返回Something with Avocado (id: 1)


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

它应该返回Something w Avocado, Chocolate and raw oatmeal (id: 2)

我怎样才能做到这一点?

我正在使用 Laravel,如果您能利用 Eloquent,那就太好了。

编辑:

感谢@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');
})

显然这段代码属于过滤搜索,所以我希望这可以帮助某人。

【问题讨论】:

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


    【解决方案1】:

    您可以使用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 ;
    

    【讨论】:

    • 在案例声明中,nr.type 应该是 n.type,不是吗?
    • @FranciscoDaniel。 . .是的。那是错误的别名。
    【解决方案2】:
    $get = nutrients::whereIn('type', ['type one', 'type two'])->get();
    

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

    【讨论】:

      猜你喜欢
      • 2016-03-25
      • 2014-10-21
      • 2021-07-22
      • 1970-01-01
      • 2019-06-20
      • 1970-01-01
      • 2016-08-04
      • 2015-06-18
      • 2023-01-22
      相关资源
      最近更新 更多