Получить записи, которые имеют все конкретные отношения - PullRequest
0 голосов
/ 18 января 2019

У меня есть следующая схема:

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 Было бы здорово, если бы вы воспользовались Eloquent .

Edit:

Благодаря @ 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 голосов
/ 18 января 2019
$get = nutrients::whereIn('type', ['type one', 'type two'])->get();

затем сохраните его в другой таблице.

0 голосов
/ 18 января 2019

Вы можете использовать group by и 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 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 ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...