Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / MySQL Новый топик    Ответить
 Как сделать выборку под циклом (каждый последующий запрос - к результату предыдущего)  [new]
atillus
Member

Откуда:
Сообщений: 11
Добрый день!
Хочу сделать одним запросом следующее:

SELECT * FROM `properties` WHERE `field_1` = 'some_value' AND `field_2` = 'some_other_value';
цикл {
SELECT * FROM [результат предыдущего SELECT] WHERE `field_1` = 'some_value' AND `field_2` = 'some_other_value';
}


Собственно, задача в чем:

В таблице хранятся свойства товаров... Структура таблицы такова: id|prod_id|feature_id|value

Связи:
prod_id => id из таблицы products
feature_id => id из таблицы features

Мне нужно получить товары, у которых нужный мне feature_id и value и при этом фильтров может быть несколько...
28 сен 17, 16:42    [20829590]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку под циклом (каждый последующий запрос - к результату предыдущего)  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 16230
atillus
фильтров может быть несколько...

В зависимости от логики фильтры объединяются операторами OR либо AND. В одном запросе, без наворотов.
28 сен 17, 16:48    [20829618]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку под циклом (каждый последующий запрос - к результату предыдущего)  [new]
atillus
Member

Откуда:
Сообщений: 11
Akina, не получается так...

Вот почему:

[CSV]
id,prod_id,feature_id,value
1,234,3,зеленый
2,237,3,красный
3,245,4,большой
3,246,4,маленький
[CSV]

-- если так
WHERE ( feature_id = 3 AND value = 'зеленый' ) AND ( feature_id = 4 AND value = 'большой' )
-- результат: ноль

-- если так
WHERE ( feature_id = 3 AND value = 'зеленый' ) OR ( feature_id = 4 AND value = 'большой' )
-- результат: все
28 сен 17, 16:59    [20829665]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку под циклом (каждый последующий запрос - к результату предыдущего)  [new]
atillus
Member

Откуда:
Сообщений: 11
Я сделал для образца небольшой пример (облегченный и упрощенный) - дамп приложил.

Если делать так:

SELECT DISTINCT products.id, products.prod_name FROM products
LEFT JOIN properties ON properties.prod_id = products.id
WHERE properties.feature_id = 1 AND properties.value = 'черный'
OR properties.feature_id = 2 AND properties.value = '41'


то получим и все черные, и все 41-го размера

А если так:

SELECT DISTINCT products.id, products.prod_name FROM products
LEFT JOIN properties ON properties.prod_id = products.id
WHERE properties.feature_id = 1 AND properties.value = 'черный'
AND properties.feature_id = 2 AND properties.value = '41'


то не получим ничего...

Поэтому я ищу возможность поочередно применять условия к предыдущему результату...

К сообщению приложен файл (temp_sql.sql - 3Kb) cкачать
28 сен 17, 17:57    [20829893]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку под циклом (каждый последующий запрос - к результату предыдущего)  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 16230
Следует выбрать все записи с нужными комбинациями (feature_id,value), сгруппировать по продукту и подсчитать количество отобранных для продукта записей.

SELECT products.id, products.prod_name 
FROM products
INNER JOIN properties ON properties.prod_id = products.id
-- можно и так
-- WHERE (properties.feature_id = 1 AND properties.value = 'черный')
-- (OR properties.feature_id = 2 AND properties.value = '41')
-- но нагляднее так 
WHERE (properties.feature_id, properties.value) IN ((1, 'черный'), (2, '41'))
GROUP BY products.id 
-- если Server Mode = ONLY_FULL_GROUP_BY, то ещё и 
--                  , products.prod_name 
HAVING COUNT( -- если возможно дублирование записей
--           DISTINCT 
                      products.id) = 2
28 сен 17, 19:52    [20830086]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать выборку под циклом (каждый последующий запрос - к результату предыдущего)  [new]
atillus
Member

Откуда:
Сообщений: 11
Akina, спасибо. То, что нужно! GROUP BY и затем HAVING COUNT - самое верное решение.
28 сен 17, 20:02    [20830105]     Ответить | Цитировать Сообщить модератору
Все форумы / MySQL Ответить