Форматирование запроса ПРАВИЛЬНОГО СОЕДИНЕНИЯ с несколькими объединениями

#mysql #sql #database #group-by #subquery

#mysql #sql #База данных #группировка по #подзапрос

Вопрос:

У меня есть SQL-запрос, который работает:

 SELECT table1.bike_id 
FROM
    ( 
        SELECT bike_id 
        FROM `bike_filters`
        WHERE (`bike_category_id` in (416,11111)) 
    ) as table1
    RIGHT JOIN (
        SELECT bike_id 
        FROM `bike_filters`
        WHERE (`bike_category_id` in (5555,779)) 
    ) as table2 ON table1.bike_id = table2.bike_id
GROUP BY bike_id
  

Но мне нужно добавить еще RIGHT JOIN s строк, возможно, 5 или больше. Как правильно сформировать запрос? Я ищу в одной таблице, но объединяю несколько записей в одном запросе, чтобы получить bike_id, который соответствует всем условиям.

Цель этого запроса — получить bike_id s, у которого есть все параметры по запросу — bike может иметь 20 фильтров, но если пользователь выполняет поиск по 5 и bike им соответствует, мы получаем bike_id по этому запросу.

Структура таблицы:

 | id | bike_id | bike_category_id |
| 1  | 3       | 416              |
| 2  | 3       | 779              |
| 3  | 3       | 344              |
| 4  | 3       | 332              |
| 5  | 4       | 444              |
| 5  | 5       | 555              |
  

Мне нужно что-то вроде этого, это неверно:

 SELECT table1.bike_id 
FROM
    ( 
        SELECT bike_id 
        FROM `bike_filters` 
        WHERE (`bike_category_id` IN (416,11111)) 
    ) AS table1
    RIGHT JOIN ( 
        SELECT bike_id 
        FROM `bike_filters` 
        WHERE (`bike_category_id` IN (5555,779)) 
    ) AS table2
    RIGHT JOIN ( 
        SELECT bike_id 
        FROM `bike_filters` 
        WHERE (`bike_category_id` IN (5555,344)) 
    ) AS table3
    RIGHT JOIN ( 
        SELECT bike_id 
        FROM `bike_filters` 
        WHERE (`bike_category_id` IN (5555,332)) 
    ) AS table4
GROUP BY bike_id
  

Комментарии:

1. Вы говорите «но если пользователь выполняет поиск по 5 и bike им соответствует, мы получаем bike_id по этому запросу» . Соответствует 1 из них или всем 5?

2. @JimCastro соответствует всем пяти!

Ответ №1:

Вы можете использовать агрегацию и поместить все условия в HAVING предложение следующим образом:

 SELECT bike_id
FROM bike_filters
GROUP BY bike_id
HAVING
   MAX(bike_category_id in (416,11111)) = 1
   AND MAX(bike_category_id in (5555,779)) = 1
  

Это вернет все bike_id , которые :

  • иметь категорию 416 или 11111
  • и имеют категорию 5555 или 779

Вы можете расширить HAVING предложение в соответствии с вашими требованиями.