MySQL получить пересечение нескольких строк - PullRequest
1 голос
/ 13 марта 2020

У меня есть структура таблицы (recipe_categories), как показано ниже

recipe_id   sub_category_id
1           2
1           3
1           5
2           3
2           5
3           2
3           5

Я получаю sub_category_id от API (через запятую), и я хочу recipe_id, который имеет все sub_category_id

Пример: 1) если пользователь передает sub_category_id 3,5 в API, то ID 1 и 2 рецепта имеют sub_category_id 3 и 5, здесь recipe_id 3 будет игнорироваться, поскольку имеет только sub_category_id 5, а не 3, поэтому результат recipe_id 1 и 2

2) если пользователь передаст sub_category_id 2,3,5, поэтому результат будет только recipe_id 1

При PHP я попытался взорвать идентификаторы и создал MySQL запрос, как показано ниже, и он работает:

 SELECT * FROM 
      ( SELECT *,GROUP_CONCAT(sub_category_id) as
      subcat FROM `recipe_categories` group by recipe_id
      ORDER BY `id` DESC )
    as a where find_in_set('5',subcat)
    and find_in_set('6',subcat) and find_in_set('7',subcat)

Здесь, используя для l oop Я сделал несколько find_in_set

Так что мой вопрос, есть ли лучший способ что я могу найти ожидаемый результат непосредственно из запроса MySQL, не создавая запрос с использованием PHP.

Ответы [ 2 ]

3 голосов
/ 13 марта 2020

Вот канонический способ обработки вашего требования:

SELECT recipe_id
FROM recipe_categories
WHERE sub_category_id IN (3, 5)
GROUP BY recipe_id
HAVING COUNT(DISTINCT sub_category_id) = 2;

Возможно, вам потребуется проделать некоторую дополнительную работу, чтобы реализовать это из PHP, используя подготовленное утверждение.

2 голосов
/ 13 марта 2020

Вы можете реализовать это в общем случае c (требуя только передачу строки, разделенной запятыми, в качестве параметра), подсчитав число совпадающих sub_category_id (используя FIND_IN_SET для их поиска) и сравнив это с числом значений в строке (которые можно определить путем вычитания длины с запятыми, удаленными из исходной длины):

SELECT recipe_id
FROM recipe_categories
WHERE FIND_IN_SET(sub_category_id, '2,3,5')
GROUP BY recipe_id
HAVING COUNT(DISTINCT sub_category_id) = LENGTH('2,3,5') - LENGTH(REPLACE('2,3,5', ',', '')) + 1

Вывод (для данных выборки)

recipe_id
1

Демо на dbfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...