У меня есть таблица с именем clothes_properties, и некоторые строки выглядят так:
id product_id property_name property
55 189000 color blue
56 189000 type tshirt
57 189000 size medium
58 189001 color red
59 189001 type tshirt
60 189001 size medium
Я хотел бы создать SQL-запрос, который может выбрать правильный product_id из того, что ищет пользователь. Так что, если пользователь ищет футболку и средний, я хочу, чтобы SQL-запрос возвращал: 189000 & 189001. И если пользователь ищет футболку и синий, я хочу, чтобы был возвращен только этот идентификатор продукта: 189000. Как я могу создать запрос SQL, который делает это?
Такого рода таблицы часто называют хранилищем ключей / значений. Это правильный способ обработки расширяемого списка свойств, но он может быть немного сложным в использовании.
Такой запрос даст вам product_id
значения в том порядке, в котором они соответствуют вашему списку критериев, лучше всего подбирать в первую очередь. (http://sqlfiddle.com/#!9/7870b5/2/0)
select count(*) matches, product_id
from prop
where property in ('tshirt','medium')
group by product_id
order by 1 desc
Этот запрос не знает о разнице между размером, цветом и типом.
Если вы хотите точно подобрать размер, цвет и т. Д., Он становится немного сложнее. Вам нужно начать с запроса, который поворачивает таблицу свойств ключ / значение — превращает строки в столбцы. (http://sqlfiddle.com/#!9/7870b5/3/0)
select id.product_id,
color.property color,
type.property type,
size.property size
from (select distinct product_id from prop) id
left join prop color on id.product_id = color.product_id and color.property_name = 'color'
left join prop type on id.product_id = type.product_id and type.property_name = 'type'
left join prop size on id.product_id = size.product_id and size.property_name = 'size'
Затем вам нужно обработать это как виртуальную таблицу и запросить ее, возможно, так. (http://sqlfiddle.com/#!9/7870b5/4/0)
select *
from (
select id.product_id,
color.property color,
type.property type,
size.property size
from (select distinct product_id from prop) id
left join prop color on id.product_id = color.product_id and color.property_name = 'color'
left join prop type on id.product_id = type.product_id and type.property_name = 'type'
left join prop size on id.product_id = size.product_id and size.property_name = 'size'
) allprops
where size='medium' and color = 'blue'
Многие разработчики и dbas создадут вид, похожий на allprops
чтобы сделать это немного проще.
Вы хотите полностью игнорировать property_name
столбец?
SELECT DISTINCT product_id
FROM clothes_properties
WHERE property IN ('tshirt', 'medium');
SELECT DISTINCT product_id
FROM clothes_properties
WHERE property IN ('tshirt', 'blue');
Я бы сделал это используя GROUP BY
а также HAVING
:
select product_id
from clothes_properties
where property_type = 'type' and property = 'tshirt' or
property_type = 'size' and property = 'medium'
group by product_id
having count(distinct property_type) = 2;
Обратите внимание distinct
не требуется, если у вас нет повторяющихся типов свойств для данного продукта.
Если вы хотите что-то общее, вы можете использовать:
select product_id
from clothes_properties
where property_type = 'type' and (property = $type or $type = '') or
property_type = 'size' and (property = $size or $size = '') or
property_type = 'color' and (property = $color or $color = '')
group by product_id
having count(distinct property_type) = (($type <> '') + ($size <> '') + ($color <> ''));
Попробуй это
SELECT DISTINCT(product_id) FROM clothes_properties WHERE property IN ('tshirt','medium')
group by product_id
having count (distinct property) = 2