|
|
|
|
|
для: sms-send
(23.07.2010 в 16:34)
| | Собственно для чего задумывалось это все извращение.
В первую очередь не для того чтобы фильтровать, исходя из значений параметров. А чтобы можно было вывести количество товаров у которых параметр равен одному из вариантов его значения
Цвет
белый 160
черный 100
синий 20
фиолетовый 20
Материал
хлопок 200
мешковина 1
шелк 40
синтетика 59
|
Собственно такой вариант решается простым IF
SUM(IF(`param_id` = 2 AND `value` = "белый", 1, 0)) as "2.белый",
SUM(IF(`param_id` = 2 AND `value` = "черный ", 1, 0)) as "2.черный ",
SUM(IF(`param_id` = 2 AND `value` = "синий ", 1, 0)) as "2.синий ",
|
Но, еще к этому нужно вывести вот такой вариант
Качество майки
Хорошее(цвет белый,черный,синий + материал хлопок, шелк) 240
Среднее(цвет любой, материал синтетика) 59
Плохое(цвет любой, материал мешковина ) 1
|
Это как раз таки составной фильтр, и его нельзя сделать в одном запросе с IF. Вот если все параметры в виде колонок, то легко.
Надеюсь я не намудрил с объяснением | |
|
|
|
|
|
|
|
для: Ученик
(23.07.2010 в 15:46)
| | Если запрос формируется на основании поисковой формы, то самое простое - ограничить пользователя в количестве задаваемых условий поиска (всё равно десяток-другой фиксированных параметров скорей всего обрежет множество до 0).
Количество JOIN'ов в данном запросе можно сократить в 2 раза, если заранее выбрать все используемые идентификаторы параметров из таблицы `params` и подставлять их в запрос "вручную".
Если 60 параметров мало, можно выполнять запросы по 60 JOIN'ов, а потом пересекать полученные товары по полю `tovar`.`tovar_id`.
SELECT *
FROM
`tovar`
WHERE
`tovar_id` IN (SELECT `tovar_id` FROM ... запрос с первыми 60 параметрами)
AND
`tovar_id` IN (SELECT `tovar_id` FROM ... запрос со вторыми 60 параметрами)
|
Можно отказаться от гибкости и пустить таблицу `tovar` на денормализацию расти в ширину - для каждого аттрибута создать отдельное поле. Если у какого то товара не будет конкретного аттрибута, то в соответствующем поле будет NULL. Но врятли такую кучу можно будет заставить быстро работать. | |
|
|
|
|
|
|
|
для: Ученик
(23.07.2010 в 11:36)
| | Может вы еще подскажите как решить проблему если у товара больше 30 параметров?
Иначе рискуем увидеть такое сообщение
mysql can only use 61 tables in a join
|
Кстати запрос на реальной базе в сотни тысяч товаров, и миллионы параметров выполняется довольно быстро) | |
|
|
|
|
|
|
|
для: sms-send
(23.07.2010 в 10:57)
| | Спасибо большое, все оказалось и правда просто.
Признаюсь честно даже не знал что можно использовать такую конструкцию
(`param1`.`param_name`, `param1_val`.`param_value`)=("цвет", "белый")
|
PS В вашем коде есть небольшая опечатка, но кому этот запрос пригодится думаю разберутся в чем проблема;) | |
|
|
|
|
|
|
|
для: Trianon
(23.07.2010 в 11:08)
| | Соглашусь.
Но так будет удобней условие выборки формировать в одном месте:
(`param1`.`param_name`, `param1_val`.`param_value`)=("цвет", "чёрный")
AND
(`param2`.`param_name`, `param2_val`.`param_value`)=("материал", "мешковина")
|
Если бы было:
INNER JOIN `tovar_params` AS `param_color_val` ON `tovar`.`tovar_id`=`param_color_val`.`tovar_id`
INNER JOIN `params` as `param_color` ON `param_color_val`.`param_id`=`param_color`.`param_id`
| согласился бы без возражений. | |
|
|
|
|
|
|
|
для: sms-send
(23.07.2010 в 10:57)
| | вот тут куски условий, живущие в WHERE ну просто в голос кричат "Переселите нас в соотв.join-ON!" | |
|
|
|
|
|
|
|
для: Ученик
(23.07.2010 в 01:04)
| | > Если бы она была в виде колонок, было бы совсем просто.
SELECT
`tovar`.*,
`param1_val`.`param_value` AS `цвет`,
`param2_val`.`param_value` AS `материал`
FROM
`tovar`
INNER JOIN `tovar_params` AS `param1_val` ON `tovar`.`tovar_id`=`param1`.`tovar_id`
INNER JOIN `params` as `param1` ON `param1_val`.`param_id`=`param1`.`param_id`
INNER JOIN `tovar_params` AS `param2_val` ON `tovar`.`tovar_id`=`param2_val`.`tovar_id`
INNER JOIN `params` as `param2` ON `param2_val`.`param_id`=`param2`.`param_id`
WHERE
`param1`.`param_name`="цвет"
AND
`param2`.`param_name`="материал"
|
| |
|
|
|
|
|
|
|
для: sms-send
(23.07.2010 в 10:18)
| | Вот видите, когда вас и Trianon`a нет, ошибки некому поправить :)))
SELECT COUNT( * ) cnt
FROM tovar t
LEFT JOIN tovar_params tp ON tp.tovar_id = t.tovar_id
LEFT JOIN params pr ON pr.param_id = tp.param_id
WHERE (tp.param_value = 'белый'
OR tp.param_value = 'мешковина' ) AND pr.param_id IN(3,4,5,6)
|
| |
|
|
|
|
|
|
|
для: Лена
(23.07.2010 в 10:05)
| |
WHERE tp.param_value = 'белый'
AND tp.param_value = 'мешковина'
|
tp.param_value должен разорваться и принимать одновременно (AND) два разных значения?)) | |
|
|
|
|
|
|
|
для: Ученик
(23.07.2010 в 01:04)
| | >Смотрите
>param_id 2 это цвет
>param_id 3 это материал
>В вашем последнем запросе это не учтено, но если и добавить
>
WHERE (tp.param_value = 'белый' AND pr.param_id = 2)
>AND (tp.param_value = 'мешковина' AND pr.param_id = 3)
|
Ну я вам разве так говорила...
SELECT COUNT( * ) cnt
FROM tovar t
LEFT JOIN tovar_params tp ON tp.tovar_id = t.tovar_id
LEFT JOIN params pr ON pr.param_id = tp.param_id
WHERE tp.param_value = 'белый'
AND tp.param_value = 'мешковина' AND pr.param_id IN(3,4,5,6)
|
| |
|
|
|
|