MySQL, SQL-запрос в несколько строк

У меня есть таблица с именем 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, который делает это?

2

Решение

Такого рода таблицы часто называют хранилищем ключей / значений. Это правильный способ обработки расширяемого списка свойств, но он может быть немного сложным в использовании.

Такой запрос даст вам 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 чтобы сделать это немного проще.

1

Другие решения

Вы хотите полностью игнорировать 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');
0

Я бы сделал это используя 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 <> ''));
0

Попробуй это

SELECT DISTINCT(product_id) FROM clothes_properties WHERE property IN ('tshirt','medium')
group by product_id
having count (distinct property) = 2

0
По вопросам рекламы [email protected]