выбор значений нескольких полей

zuxel

Новичок
выбор значений нескольких полей

Здравствуйте! Пишу сайт-каталог, у каждого товара есть характеристики, их значения записаны в таблицу, в которой есть поля product_id, field_id, value.
Нужно сделать поиск по характеристикам, пробывал вот так:
PHP:
SELECT * FROM cat_fields_values WHERE ( value = '744' AND field_id = '7' ) 
AND ( value = '741' AND field_id = '6' ) 
AND ( value = '2' AND field_id = '11' ) 
AND ( ( value > '11' AND value < '22' ) 
AND field_id = '10' )
но не работает.
Причем, есть такой момент, что для некоторых полей можно не только просто сравнивать равно или не равно, а выбирать значения находящиеся между заданными пользователями значениями. Я пробывал это сделать так: AND ( ( value > '11' AND value < '22' ) AND field_id = '10' )
Подскажите, пожайлуста, как сделать выборку?
 

Ewg

Новичок
http://www.google.ru/#hl=ru&source=hp&q=mysql+in&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+Google&lr=&aq=f&oq=mysql+in&fp=3af9973a18a5c45f
 

zuxel

Новичок
Спасибо, не подумал сразу, но им можно вот это разве сделать:
Причем, есть такой момент, что для некоторых полей можно не только просто сравнивать равно или не равно, а выбирать значения находящиеся между заданными пользователями значениями
?
 

Mols

Новичок
zuxel
Ясное дело не работает... как может быть одновременно value = '744' и value = '741' и т.п.?
Я бы выбирал это всё с помощью UNION.
 

phprus

Moderator
Команда форума
Mols
Думаю, что тебе стоит узнать про существование OR прежде чем давать советы.
 

Mols

Новичок
phprus
Да? хм.. думаю тебе лучше посмотреть EXPLAIN в случае с OR в случае с UNION... прежде, чем давать советы. ;)
З.Ы.
Хотя я думаю ты об этом знаешь. Можно конечно начать рассказывать, что неизвестно есть ли вообще индексы на столбце field_id и т.п. Надеюсь, что есть ;)

-~{}~ 09.01.10 18:11:

Да и фразу "Я бы выбирал это всё с помощью UNION. " уж очень странно рассматривать как совет)))
 

phprus

Moderator
Команда форума
Mols
MySQL под рукой нету, так что протестировать увы не смогу, но запросы в PostgreSQL к табличке на 75к записей из которых выбиралось около 5,5к что с UNION ALL, что с OR отработали за примерно одинаковое время (индекс есть). А если использовать просто UNION, так как он по смыслу больше похож на поведение OR (в отличие от UNION ALL), то такой вариант отработал примерно на 5% медленнее.
Если-же смотреть на cost в Explaine, то вариант с OR чуть-чуть более быстр, чем вариант с UNION.
В общем с учетом того, в каких условиях я проводил тесты можно считать, что в моем случае они дали одинаковую производительность.

А как поведет себя MySQL в подобной ситуации?

Да и фразу "Я бы выбирал это всё с помощью UNION. " уж очень странно рассматривать как совет)))
Согласен, что странно, но мне она изначально почему-то показалась советом.
 

Mols

Новичок
При чем тут UNION ALL я не понял. У ТС вроде условия такие, что дублирующихся записей не будет по любому.
А по теме... Честно говоря я уже не помню с чего я взял(очень давно это было), что OR в такой ситуации приведёт к полному скану таблицы... но вот сейчас не поленился проверить. Оказалось, не приводит(использует индексы зараза). Что меня, откровенно сказать, сильно удивило. Видать надо мне действительно пойти почитать о том, как OR работает.
 

prolis

Новичок
Автор оригинала: Mols
OR в такой ситуации приведёт к полному скану таблицы... но вот сейчас не поленился проверить. Оказалось, не приводит(использует индексы зараза). Что меня, откровенно сказать, сильно удивило. Видать надо мне действительно пойти почитать о том, как OR работает.
[sql]
select * from table where field=1 or field=2
[/sql]
интерпретируется как:
[sql]
select * from table where field in (1,2)
[/sql]
 

zuxel

Новичок
Вариант с OR не подходит, т.к. мне надо чтобы выбирались записи у которых есть все заданные в поиске характеристки, а так выбираются записи у которых например только ( value = '744' AND field_id = '7' ), а значение field_id = '6' вообще не определено
 

phprus

Moderator
Команда форума
zuxel
Так у тебя оказывается для одного product_id свойства в разных строках твоей таблицы хранятся. Те это некие EAV.
Тогда попробуй решить задачу через OR, GROUP BY product_id, count(product_id), HAVING.
 

zuxel

Новичок
на другом форуме нашел вот такое решение:
PHP:
select product_id
from tabName
where field_id in ('1', '2', '3') and `value` in ('11', '22', '33')
group by product_id
having sum(if(`value` = '11' AND field_id = '1', 1, 0)) > 0
   and sum(if(`value` = '22' AND field_id = '2', 1, 0)) > 0
   and sum(if(`value` = '33' AND field_id = '3', 1, 0)) > 0;
, но еще не попробывал.

А куда можно count(product_id) приткнуть?
 

phprus

Moderator
Команда форума
Например так приткнуть:
Код:
select product_id
from tabName
where (`value` = '11' AND field_id = '1') OR (`value` = '22' AND field_id = '2') OR (`value` = '33' AND field_id = '3')
group by product_id
having count(product_id) = 3
Логика такая, что если выбралось 3 строки для product_id, то значит выполнились все 3 условия одновременно.
 
Сверху