[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Множественная выборка
Arh
Не знаю как назвать тему или каким запросом спросить у гула =(

Помогите разобраться.
Пытаюсь сделать фильтр товаров.

Есть таблица с товарами, назовём её products (Описание товаров)
Есть таблица с характеристиками (фильтрами) params_desc (Описание характеристик)
И есть таблица с сопоставлениями товаров с характеристиками params (Сопоставление)

Предположим есть товар (№1), у которого три характеристики (деревянный, чёрный, круглый)
Есть еще один товар (№2) с тремя характеристиками (каменный, чёрный, квадратный)

Если поставить галочки например чёрный и каменный, то по идее должен вывестись товар №2, так как он каменный и чёрный. Вот как это сделать?

param_id = 1; это чёрный 
param_id = 2; это каменный
эти характеристики описаны в таблице params_desc
а в таблице params, сопоставляется id характеристики c id товара. то есть у товара может быть сколько угодно характеристик.


Типа такого запроса не работает (WHERE AND)
SELECT * FROM products pro
LEFT JOIN params par ON par.`product_id` = pro.`id`
LEFT JOIN params_desc pd ON pd.`id` = par.`param_id`
WHERE par.`param_id` = 1 AND par.`param_id` = 2


А такой работает (WHERE OR)
SELECT * FROM products pro
LEFT JOIN params par ON par.`product_id` = pro.`id`
LEFT JOIN params_desc pd ON pd.`id` = par.`param_id`
WHERE par.`param_id` = 1 OR par.`param_id` = 2


Но второй запрос выводит два товара, так как они оба чёрные, а нужен товар который и чёрный и каменный одновременно.


user posted image

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
CoDy

SELECT
pro.*
FROM
(
SELECT DISTINCT
par.product_id
FROM
params AS par
WHERE
par.param_id = 1
AND par.param_id = 2
) AS prd_lst
INNER JOIN
products AS pro
ON
prd_lst = pro.id
Arh
CoDy
Тоже самое, с AND не работает с OR выводит два товара вместо одного.

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Arh
Упрощу задачу.
Есть таблица с двумя полями. param и product
Нужно вывести product у которого param равен 1 и 2

На картинке ниже зелёным цветом показан правильный продукт у которого параметр и 1 и 2 (выделено синим)
А продукт номер 1, не должен высвечиваться, так как у него совпадает только 1 параметр

user posted image

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
CoDy
Идея следующая: выбираем все продукты, которые имеют хотяябы какойто параметр из указаных; потом считаем для каждого продукта количество параметров, которые совпали и оставляем только те продукты у которых есть ВСЕ параметры совпали:

-- выборка по 2 параметрам
SELECT
par.product_id, COUNT(DISTINCT par.product_id) AS hit
FROM
params AS par
WHERE
par.param_id = 1
OR par.param_id = 2
GROUP BY
par.product_id
HAVING
hit = 2;
-- выборка по 3 параметрам
SELECT
par.product_id, COUNT(DISTINCT par.product_id) AS hit
FROM
params AS par
WHERE
par.param_id = 1
OR par.param_id = 2
OR par.param_id = 3
GROUP BY
par.product_id
HAVING
hit = 3;


Не берусь утверждать, что это самое оптимальное решение. Возможно есть варианты по интереснее.
Arh
CoDy
Не очень понял) Но всё равно спасибо, уже сделал кое как на джойнах.

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
e-gorych
Цитата (CoDy @ 22.07.2014 - 15:33)
Идея следующая: выбираем все продукты, которые имеют хотяябы какойто параметр из указаных; потом считаем для каждого продукта количество параметров, которые совпали и оставляем только те продукты у которых есть ВСЕ параметры совпали:

-- выборка по 2 параметрам
SELECT
par.product_id, COUNT(DISTINCT par.product_id) AS hit
FROM
params AS par
WHERE
par.param_id = 1
OR par.param_id = 2
GROUP BY
par.product_id
HAVING
hit = 2;
-- выборка по 3 параметрам
SELECT
par.product_id, COUNT(DISTINCT par.product_id) AS hit
FROM
params AS par
WHERE
par.param_id = 1
OR par.param_id = 2
OR par.param_id = 3
GROUP BY
par.product_id
HAVING
hit = 3;


Не берусь утверждать, что это самое оптимальное решение. Возможно есть варианты по интереснее.

А так не пойдет топикстартеру?

select product_id, count(product_id) as hit
from params
where param_id in (2, 4, 5)
group by product_id
having hit = 3
e-gorych
Цитата (Arh @ 22.07.2014 - 17:04)
CoDy
Не очень понял) Но всё равно спасибо, уже сделал кое как на джойнах.

Поделитесь решением, интересно smile.gif
Arh
Заюзал этот вариант, спасибо, круто придумали.

select product_id, count(product_id) as hit
from params
where param_id in (2, 4, 5)
group by product_id
having hit = 3


Теперь появилось дополнительное поле =) (максимальное/минимальное значение)
user posted image

user posted image

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.