С твоим разъяснением, Рубен, я понимаю структуру базы данных и то, что ты сейчас спрашиваешь.Я начну с наблюдения, что вам нужно использовать для запроса к базе данных одну или несколько пар спецификаций.spec_name и products_specifications.content.Как вы указали в своем вопросе, вы хотите иметь возможность использовать один или несколько из них для запроса набора продуктов, который удовлетворяет всем условиям.
Чтобы понять, почему используется только попарное сочетание spec_name и contentРазумно, рассмотрим пример, в котором продукты представляют собой автомобили, а некоторые характеристики представляют собой цвета различных компонентов (например, body_color, interior_color, racing_stripe_color).Если вы ищете автомобили с красным цветом кузова и черным цветом салона, но запрос не связывает имя_спецификации и содержимое попарно, то вы также получите автомобили с черным цветом кузова и красным цветом салона, что вам не подходит.То же самое применимо, если в какой-либо из ваших спецификаций есть числа в качестве значений.
Мой ответ использует подзапрос для возврата значений product_id, которые будут использоваться для генерации окончательного вывода, но это также можно сделать с помощью дополнительных объединений.Если запрос, использующий подзапрос, слишком медленный, возможно, вам придется попробовать другую версию.Я также собираюсь использовать «select *», хотя я настоятельно рекомендую не делать этого в производственной среде (вместо этого вы должны перечислить столбцы), так как вещи имеют тенденцию ломаться намного легче, если есть изменения в структуре базы данных.,Вы также получите некоторые столбцы с дублирующимися значениями, которые могут быть устранены путем правильного перечисления столбцов.Я предполагаю, что product_id и spec_id уникальны в таблицах продуктов и спецификаций, соответственно, и что каждая комбинация product_id и spec_id встречается не более одного раза в таблице products_specifications.
select * from (
select p1.product_id as product_id from products as p1
join products_specifications as ps1 on p1.product_id = ps1.product_id
join specifications as s1 on ps1.spec_id = s1.spec_id
where <selection conditions>
group by p1.product_id
having count(s1.spec_id) = <number of selection conditions>
) pp
join products as p on pp.product_id = p.product_id
join products_specifications as ps on p.product_id = ps.product_id
join specifications as s on ps.spec_id = s.spec_id
order by p.product_id, s.spec_name;
будет иметь вид:
(s1.spec_name = 'spec1' and ps1.content = 'spec1value')
or (s1.spec_name = 'spec2' and ps1.content = 'spec2value')
or ...
для столько пар spec_name, сколько вы хотите использовать в запросе.Вам нужно будет сгенерировать эту часть запроса вручную или в коде вызова.Вам нужно убедиться, чторавняется количеству условий таким же образом.