Это расплывчатое название, поэтому, пожалуйста, исправьте его, если вы можете подумать о лучшем.
Рассмотрите следующие 4 таблицы:
products : id (int), имя, msrp и т. д. *
субпродукты : id (int), product_id (int), name (varchar)
subproducts_properties : id (int), subproduct_id (int), property_id (int)
subproducts_properties_values : subproducts_properties_id (int), значение (varchar)
Итак, основная идея здесьзаключается в том, что один продукт может иметь несколько субпродуктов (моделей), один субпродукт может иметь несколько свойств (или спецификаций), а одно свойство субпродукта может иметь несколько значений.
Теперь представьте, что существует продукту этого есть многократные субпродукты, у которых есть много свойств, у которых есть многократные значения.В частности, этот продукт имеет субпродукт, который имеет следующие свойства:
Свойство 1 - property_id: 1;значение = '.17 HMR';
Свойство 2 - property_id: 22;value = 'Bolt';
Где property_id 1
имеет имя Caliber
, а property_id 2
имеет имя Action
(думаю: оружие).
Что это за продукт not have - это подпродукт, содержащий свойство с property_id=1
и value='5.56 mm NATO'
.
. У пользователя есть раскрывающиеся списки, в которых он может выбрать несколько наборов фильтров на основе уникальных значений.Поэтому, если пользователь выбирает Caliber
из .17 HMR
и Action
из Bolt
, он должен ожидать увидеть наш продукт, но когда он откатится назад Bolt
и Caliber
, скажем, 5.56 mm NATO
он должен видеть нет продуктов, потому что наш продукт не соответствует обоим фильтрам.
Итак ... учитывая эту информацию, я хотел бы отозвать все продуктов (один продукт на строку) в базе данных и фильтрация по нескольким значениям свойств.Моя текущая попытка выглядит следующим образом:
SELECT p.*, m.name as manufacturer_name, pt.name as product_type_name, COUNT(DISTINCT com.id) AS num_reviews, ROUND(AVG(com.rating), 1) as rating, pi.image_thumb
FROM products p
LEFT JOIN manufacturers m ON p.manufacturer_id=m.id
LEFT JOIN product_types pt ON p.product_type_id=pt.id
LEFT JOIN comments com ON p.id=com.object_id AND com.object_group = 'com_products' AND com.level=0
LEFT JOIN (
SELECT product_id, thumb_path as image_thumb
FROM products_images pi
ORDER BY ordering ASC
) AS pi ON p.id=pi.product_id
LEFT JOIN subproducts sp ON p.id=sp.product_id
LEFT JOIN subproducts_properties spp ON sp.id=spp.subproduct_id
LEFT JOIN subproducts_properties_values sppv ON spp.id=sppv.sp_id
WHERE p.deleted != 1 AND p.published=1
AND (
IF(spp.property_id=1, IF(sppv.value='5.56 mm NATO',1,0), 0) = 1
OR IF(spp.property_id=22, IF(sppv.value='Bolt',1,0), 0) = 1
)
GROUP BY p.id
ORDER BY p.created DESC
LIMIT 0, 12
Часть, на которой нужно сосредоточиться, является последней AND
в предложении WHERE
, где я пытаюсь запустить фильтры.Также обратите внимание, что у меня есть GROUP BY
, чтобы иметь возможность выполнять агрегатные функции в других таблицах.Этот конкретный запрос отзовет наш продукт из-за OR
внутри этого последнего AND
, но я бы хотел настроить его так, чтобы в этом случае он не откатывался назад, а откатывался назад, если вместо sppv.value='5.56 mm NATO'
есть sppv.value='.17 HMR'
(это значение для нашего субпродукта).
Я попытался вместо этого вставить AND, но он ничего не возвращает, потому что у каждого значения есть собственная строка вsppv table.
Пожалуйста, помогите!Я полностью потерян для того, что делать здесь.
Заранее спасибо!