SQL-запрос с двумя разными фильтрами - PullRequest
0 голосов
/ 02 октября 2019

У меня есть страница, которая показывает все автомобили из БД. У меня есть два фильтра, оба фильтра множественного выбора. Например

фильтр 1 - Цвет

Красный, зеленый, синий <- Все эти флажки, могут быть выбраны несколько </p>

фильтр 2 - марка

BMW, Honda, Hyundai <- Все эти флажки, можно выбрать несколько </p>

Я сделал ниже запрос

Select * from cars
JOIN term_car_relationships  
ON cars.id = term_cars_relationships.car_id 
 WHERE term_cars_relationships.term_id in (6,2,3) 
GROUP BY cars.id

В приведенном выше запросе term_id

6 = синий (цвет)

2 = зеленый (цвет)

3 = BNW (марка)

Но с помощью вышеприведенного запроса я получу все автомобили, которые имеют синий цвет или зеленый цвет или марку BMW. Но как это изменить, чтобы получить BMW синего или зеленого цвета.

У меня 3 таблицыкоторая обрабатывает эти категории.

таблица таксономии

taxonomy_id | taxonomy_title
1           | Color
2           | Brand

term_list

term_id  |  term_name  |  taxonomy_id
1        | Blue        | 1
2        | Red         | 1
3        | BMW         | 2
4        | Honda       | 2

term_cars_relationships Таблица

 term_id | car_id   
     1      |  1
     1      |  2
     2      |  3

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Вы должны присоединиться к таблице term_cars_relationships дважды:

    SELECT * FROM cars
    JOIN term_car_relationships c ON cars.id = c.car_id 
    JOIN term_car_relationships b ON cars.id = b.car_id 
    WHERE c.type_of_category = 'color'
    AND b.type_of_category = 'brand'
    AND c.term_id in (6,2)
    AND b.term_id in (3)
    GROUP BY cars.id

Обратите внимание, что я использовал b.term_id in (3) вместо b.term_id = 3, поскольку я предположил, что вы можете выбрать несколько брендов.

0 голосов
/ 02 октября 2019

Вы можете создать свой запрос с отдельными объединениями для каждой категории терминов и с отдельными условиями фильтрации для каждого из них.

SELECT cars.*, colorTerms.*, brandTerms.* 
FROM cars
INNER JOIN term_car_relationships AS carColorTerms
   ON cars.id = carColorTerms.car_id
INNER JOIN term_list AS colorTerms 
   ON carColorTerms.term_id = colorTerms.term_id AND colorTerms.taxonomy_id = 1
INNER JOIN term_car_relationships AS carBrandTerms
   ON cars.id = carBrandTerms.car_id
INNER JOIN term_list AS brandTerms 
   ON carBrandTerms.term_id = brandTerms.term_id AND brandTerms.taxonomy_id = 2
WHERE colorTerms.term_id IN (6, 2)
   AND brandTerms.term_id IN (3)

Конечно, для создания этого запроса вам необходимо знать термины 'типы перед запросом.


Кроме того, использование GROUP BY cars.id без агрегирования, вероятно, является признаком проблемы или просто не правильным способом получить то, что вы хотите. Если вам нужна только информация из таблицы cars, вам нужно просто SELECT DISTINCT cars.*. Использование GROUP BY таким образом приведет к результатам с данными только одного совпадения по цветовой марке для каждого автомобиля.


При сложном редактировании исходного вопроса появилась еще одна возможность....

SELECT cars.* -- You should really just select the fields you want, and may have to in some configurations (see GROUP BY)
FROM cars AS c
INNER JOIN term_car_relationships AS tcr ON c.car_id = tcr.car_id
INNER JOIN term_list AS tl ON tcr.term_id = tl.term_id
WHERE tcr.term_id IN (6, 2, 3)
GROUP BY cars.car_id -- In some configurations of MySQL, and most other RDBMSes, you must specify every SELECTed non-aggregated field here
HAVING COUNT(DISTINCT tl.taxonomy_id) 
   = ( SELECT COUNT(DISTINCT taxonomy_id) 
       FROM term_list 
       WHERE term_id IN (6, 2, 3)
     )

Примечание. Это окончательное решение на самом деле не требует, чтобы вы больше знали термины таксономии раньше, и не растет, поскольку необходимо поддерживать больше таксономий;так что, хотя это немного менее очевидно с тем, что он делает, вероятно, определенно стоит подумать.

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