Mysql HAVIN COUNT и WHEN THEN в MYSQL нужен HELP

social_project

Новичок
Приветствую. Помогите пожалуйста с WHEN и HAVING кодом.

В общем суть такова, это поисковый фильтр, и пока человек не выберет несколько возможныж значений, все работает верно, но когда есть процедура OR в условиях, то count может вернуть не 3 а только 1 вхождение например, ну т.е. тогда увеличивать число HAVING count > 1 нельзя. Как тогда сделать что бы в выборке одно условие с OR считалось как 1 в выдаче?


Если не совсем понятно описал то вот пример:
есть товар СМАРТФОН, и значения РАЗМЕР и ЦВЕТ. Если выбран РАЗМЕР 220см, то первая выдача верная и HAVING count > 1 верно. Если выбрать еще цвет, СИНИЙ напрмиер то тоже все ок, HAVING count > 1 снова 1. Но если ставят два цвета "СИНИЙ, ЗЕЛЕНЫЙ" то HAVING count надо ставить уже 2, но тут проблема т.к. тогда покажет куча лишних вхождений т.е. элемент OR тогда я снова делать -1 от финального значения, т.е. HAVING count > 1 но тогда в выдаче бывает каша т.е. берутся уже левые товары в выдаче.

Как-то можно объединить эти элементы по GROUP внутри WHEN или как обойти данную ошибку?


Код:
(SELECT scp.`shop_cat_page_id` , COUNT(*) as count FROM `shop_catalog_page` AS `scp`
   INNER JOIN shop_catalog_page_properties AS scpp ON scpp.shop_catalog_page_properties_producer_extend = scp.shop_cat_page_producer_extend AND scpp.shop_catalog_page_properties_product_id = scp.shop_cat_page_id  AND (
   CASE
   
     WHEN shop_catalog_page_properties_parentid='748' THEN (  shop_catalog_page_properties_types_value_int='2954'  )
     WHEN shop_catalog_page_properties_parentid='747' THEN (  shop_catalog_page_properties_types_value_int='2694'  OR  shop_catalog_page_properties_types_value_int='2695'  OR  shop_catalog_page_properties_types_value_int='2700'  )
   ELSE NULL
   END
  )
  WHERE  shop_cat_page_product_type="629"
  
   GROUP BY shop_cat_page_id
   HAVING count > 1
  )
 

AnrDaemon

Продвинутый новичок
1. А зачем у тебя INNER JOIN?
2. Ты неправильно ставишь вопрос. У тебя вообще не должно быть никакого "HAVING count > 1"
 

social_project

Новичок
Это поисковый фильтр, с кучей параметров, а выбор товара в базе идет исходя из СОВПАДЕНИЯ значения характеристики в одной таблице, и товар тогда из другой таблицы выбирается. Т.е. подход наиболее оптимальный, а иначе на каждый выбранный пункт отдельный запрос -и базе капец
 

social_project

Новичок
Ну есть 2 базы. Одна с параметрами товара, вторая с товаром. Выборка из базы товаров идет (генерируя запрос на лету) потому через inner join что бы исключить те, у которых нет нужного параметра. Все бы ок, да при использовании OR может быть несколько результатов в выдаче, а не один потому и косяк с having count
 

AnrDaemon

Продвинутый новичок
Ну есть 2 базы. Одна с параметрами товара, вторая с товаром. Выборка из базы товаров идет (генерируя запрос на лету) потому через
Досюда понятно. Хотя зачем две БАЗЫ - неясно.

А вот отсюда непонтяно. Зачем тебе INNER join? У тебя что, ресурсы сервера лишние завелись? Или других режимов объединения не знаешь?…
 

social_project

Новичок
Не знаю, inner выбирает из другого поля и ТОЛЬКО при наличии выведет соовтествущее количество значений. А как по другому не знаю. Подскажи пожалуста если это не годится, то как?

Просто запросы генерируются на лету, выбрано например 10 полей и галочек в них, тогда они соотвественно через inner и CASE выбираются (товары соотвествующие этим значениям)

Другого способа не знаю и не нашел
 

social_project

Новичок
Как то можно в кейс услвоие еще IF then доабвить что бы при 3х нахождениях делать +1 к тому count числу 1, т.е. назовем ее Х. Т.е. получится



(SELECT scp.`shop_cat_page_id` , COUNT(*) as count FROM `shop_catalog_page` AS `scp`
INNER JOIN shop_catalog_page_properties AS scpp ON scpp.shop_catalog_page_properties_producer_extend = scp.shop_cat_page_producer_extend AND scpp.shop_catalog_page_properties_product_id = scp.shop_cat_page_id AND (
CASE

WHEN shop_catalog_page_properties_parentid='748' THEN ( shop_catalog_page_properties_types_value_int='2954' )
WHEN shop_catalog_page_properties_parentid='747' THEN ( ЕСЛИ НАЙДЕНО 3 то СТАВИМ Х+2 если 2 то +1 ну и если одно то ничего не меняем ТАКОЕ РЕШЕНИЕ ВОЗМОНЖНО? shop_catalog_page_properties_types_value_int='2694' OR shop_catalog_page_properties_types_value_int='2695' OR shop_catalog_page_properties_types_value_int='2700' )
ELSE NULL
END
)
WHERE shop_cat_page_product_type="629"

GROUP BY shop_cat_page_id
HAVING count > Х
)
 

social_project

Новичок
модель типа page.id
Код:
(SELECT scp.`product_id` , COUNT(*) as count FROM `product` AS `scp`
   INNER JOIN product_properties AS scpp ON scpp.product_properties_product_id = scp.product_id  AND (
   CASE
  
     WHEN product_properties_parentid='748' THEN (  product_properties_types_value_int='2954'  )
     WHEN product_properties_parentid='747' THEN (  product_properties_types_value_int='2694'  OR  product_properties_types_value_int='2695'  OR  product_properties_types_value_int='2700'  )
   ELSE NULL
   END
  )
  WHERE  product_product_type="629"
   GROUP BY product_id
   HAVING count > 1
  )
 

social_project

Новичок
продолжай сокращать
разве что так

Код:
(SELECT scp.`product_id` , COUNT(*) as count FROM `product` AS `scp`
   INNER JOIN product_properties AS scpp ON scpp.product_properties_product_id = scp.product_id  AND (
   CASE
 
     WHEN product_properties_parentid='748' THEN (  product_properties_value='2954'  )
     WHEN product_properties_parentid='747' THEN (  product_properties_value='2694'  OR  product_properties_value='2695'  OR  product_properties_value='2700'  )
   ELSE NULL
   END
  )
  WHERE  product_product_type="629"
   GROUP BY product_id
   HAVING count > 1
  )
 

WMix

герр M:)ller
Партнер клуба
case из джойна убери во where
HAVING count = n где n количество поисковых критериев
 

social_project

Новичок
case из джойна убери во where
HAVING count = n где n количество поисковых критериев
Сделал но ничего в выдаче не изменилось, из-за использования условия OR "
product_properties_value='2694' OR product_properties_value='2695' OR product_properties_value='2700'" count n будет все равно не верно считать, т.е. если бы было всего одно условия =, без OR то все ок, а когда их 3 то оно выдает лишние значения. N = количество условий WHEN



Можно как-то к каждому условию WHEN сделать свой COUNT ? Т.е. суть в том, что COUNT n считает общее количество совпадений, а оно может брать из списка OR не те товары, т.е. получается выводятся товары в которых совпало что либо из этих данных но игнорируется тогда первое условие
WHEN

Если надо могу живой пример с картинками сделать
 

WMix

герр M:)ller
Партнер клуба
PHP:
select p.*, group_concat( concat(pp.name, ': ', pp.value,' ' ) ORDER BY pp.name ) as properties
from products p
left join properties pp on p.id = pp.product_id
where
  (pp.name = "color"       and pp.value in ("black", "pink")) or
  (pp.name = "memory size" and pp.value in ("16"))
group by p.id
having count(pp.name) = 2
 
Последнее редактирование:

social_project

Новичок
Сейчас попробуйю спасибо. А касательно примера. Все же опишу пока не попробовал. Ставим бренд American Clud, находит 6 товаров. Ставим размер которых всего 2 в этом бренде, тоже все ок. А ставим еще один размер и тут же начинает вылазить не только основной бренд. Спасибо за пример буду сейчас его пробовать.

 

social_project

Новичок
Адаптировал, и почему-то в итоге найдено не 10 в результате, а 73 товара... Что еще может быть не так?

Код:
 SELECT scp.*, GROUP_CONCAT( CONCAT(scpp.shop_catalog_page_properties_parentid, ': ', scpp.shop_catalog_page_properties_types_value_int,' ' ) ORDER BY scpp.shop_catalog_page_properties_parentid ) AS shop_catalog_page_properties
FROM shop_catalog_page scp
LEFT JOIN shop_catalog_page_properties scpp ON scp.shop_cat_page_id = scpp.shop_catalog_page_properties_product_id
WHERE
  (scpp.shop_catalog_page_properties_parentid = "747"       and scpp.shop_catalog_page_properties_types_value_int in ("2694", "2695")) or
  (scpp.shop_catalog_page_properties_parentid = "748" and scpp.shop_catalog_page_properties_types_value_int in ("2954"))
GROUP BY scp.shop_cat_page_id
HAVING COUNT(scpp.shop_catalog_page_properties_parentid) = 2
 
Сверху