SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 21.11.2013 23:25:32

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Фильтрация фильтров помогите оптимизировать

Здравствуйте.
Структура таблиц фильтров товаров:
http://i.imgur.com/NArlqy9.png

Фильтрация работает так, что после выбора значения параметра фильтр показывает только те варианты которые есть у набора отфильтрованных товаров.

Например набор фильтров:
Параметр1
  -опция1_1
  -опция1_2
  -опция1_3
Параметр2
  -опция2_1
  -опция2_2
  -опция2_3

Выбираем опция1_1. После фильтрации остается

Параметр1
  -опция1_1
Параметр2
  -опция2_1
  -опция2_2

Тоесть получаем набор фильтров которые есть только у набора отфильтрованных товаров. Это жесткая фильтрация, которая упускает опции при выборе которых мы получим еще результаты -опция1_2 и -опция1_3 должна остаться в фильтрах так как они добавят товаров

Вот пример запроса выборки актуальных опций:


SELECT count(*) as total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters as pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('11'))
#-------------------Обработка опций второго параметра
AND EXISTS (SELECT 1 FROM products_parameters pv1 WHERE `pv1`.`product_id` = `pv`.`product_id`
AND `pv1`.`parameters_value_id` IN ('235', '236')) GROUP BY `parameters_value_id`
 


Помогите оптимизировать запрос так что бы из выборки фильтров не выпадали лишние фильтра или хоть подскажите в каком направлении копать. Кучу времени потратил никак не могу решить задачу, моих навыков mysql явно не хватает.

Отредактированно yuko (21.11.2013 23:27:40)

Неактивен

 

#2 22.11.2013 00:42:06

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Не очень понятно. Приведите набор тестовых данных в виде create table.. и insert into
и поясните задачу на примере этих данных, т.е. исходная величина такая-то, запрос должен сделать то-то и то-то и получиться вот такой вот результат.

Неактивен

 

#3 22.11.2013 11:58:17

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

Данные:


DROP TABLE IF EXISTS `parameters`;

CREATE TABLE `parameters` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

/*Data for the table `parameters` */

LOCK TABLES `parameters` WRITE;

insert  into `parameters`(`id`,`name`) values (1,'Параметр1'),(2,'Параметр2');

UNLOCK TABLES;

/*Table structure for table `parameters_values` */

DROP TABLE IF EXISTS `parameters_values`;

CREATE TABLE `parameters_values` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parameter_id` int(11) NOT NULL,
  `value` text COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`,`parameter_id`),
  KEY `fk_parameters_values_parameters1` (`parameter_id`),
  CONSTRAINT `fk_parameters_values_parameters1` FOREIGN KEY (`parameter_id`) REFERENCES `parameters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

/*Data for the table `parameters_values` */

LOCK TABLES `parameters_values` WRITE;

insert  into `parameters_values`(`id`,`parameter_id`,`value`) values (1,1,'опция_1_1'),(2,1,'опция_1_2'),(3,2,'опция_2_1'),(4,2,'опция_2_2'),(5,2,'опция_2_3'),(6,2,'опция_2_4');

UNLOCK TABLES;

/*Table structure for table `products` */

DROP TABLE IF EXISTS `products`;

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `watch` tinyint(1) NOT NULL DEFAULT '1',
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

/*Data for the table `products` */

LOCK TABLES `products` WRITE;

insert  into `products`(`id`,`watch`,`name`) values (1,1,'продукт1'),(2,1,'продукт2'),(3,1,'продукт3'),(4,1,'продукт4'),(5,1,'продукт5'),(6,1,'продукт6');

UNLOCK TABLES;

/*Table structure for table `products_parameters` */

DROP TABLE IF EXISTS `products_parameters`;

CREATE TABLE `products_parameters` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `parameter_id` int(11) NOT NULL,
  `parameters_value_id` int(11) DEFAULT '0',
  `value` double DEFAULT NULL,
  PRIMARY KEY (`id`,`product_id`,`parameter_id`),
  KEY `fk_products_parameters_values1` (`parameters_value_id`),
  KEY `fk_products_eshop_menus_products_products1` (`product_id`),
  KEY `fk_products_eshop_menus_products_parameters1` (`parameter_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

/*Data for the table `products_parameters` */

LOCK TABLES `products_parameters` WRITE;

insert  into `products_parameters`(`id`,`product_id`,`parameter_id`,`parameters_value_id`,`value`) values (1,1,1,1,NULL),(2,1,2,3,NULL),(3,2,1,1,NULL),(4,2,2,4,NULL),(5,3,1,2,NULL),(6,3,2,3,NULL),(7,4,1,2,NULL),(8,4,2,5,NULL),(9,5,1,1,NULL),(10,5,2,6,NULL),(11,6,1,2,NULL),(12,6,2,3,NULL);

UNLOCK TABLES;

 


Первая выборка - входящая опция "опция_1_1" параметра "Параметр1":

SELECT COUNT(*) AS total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters AS pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('1'))
GROUP BY `parameters_value_id`
 

Результат:

total    parameters_value_id    value
3    1    опция_1_1
1    3    опция_2_1
1    4    опция_2_2
1    6    опция_2_4
 

Ожидаемый результат:

total    parameters_value_id    value
3    1    опция_1_1
3    2    опция_1_2#Эта опция выпала но она нужна так как она добавит результатов если ее выбрать См.Потенциальный рез.
1    3    опция_2_1
1    4    опция_2_2
1    6    опция_2_4
 

Потенциальный рез.

SELECT COUNT(*) AS total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters AS pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('1','2'))
GROUP BY `parameters_value_id`

total    parameters_value_id    value
3    1    опция_1_1
3    2    опция_1_2
3    3    опция_2_1
1    4    опция_2_2
1    5    опция_2_3
1    6    опция_2_4
 


То что опция выпала это понятно - выпала потому, что отфильтровались все опции которых нет в наборе продуктов полученых таким запросом. Нужно оптимизировать запрос так чтоб он не откидал "потенциально" нужные опции.
Живой пример работы поожого фильтра: filter.kombox.ru/tv/

---------------------------Пример 2-----------------------
Выборка опций 2-го параметра:

SELECT COUNT(*) AS total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters AS pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('1'))
#-------------------Обработка опций второго параметра
AND EXISTS (SELECT 1 FROM products_parameters pv1 WHERE `pv1`.`product_id` = `pv`.`product_id`
AND `pv1`.`parameters_value_id` IN ('3')) GROUP BY `parameters_value_id`
 

Результат:

total    parameters_value_id    value
1    1    опция_1_1
1    3    опция_2_1
 

Ожидаемый результат:

3    1    опция_1_1#Выбрано
3    2    опция_1_2#Выпало(добавит результатов при выборе)
1    3    опция_2_1#Выбрано
1    4    опция_2_2#Выпало(добавит результатов при выборе)
1    6    опция_2_4#Выпало(добавит результатов при выборе)
 

Неактивен

 

#4 22.11.2013 12:58:22

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Ещё менее понятно стало, например, почему "опция_2_3" выпадает, а другие нет.

Есть продукты, у каждого продукта есть набор параметров, каждый параметр может принимать значение из фиксированного набора.
Вы хотите найти - вот тут словами, что вы хотите найти, без запроса.

Неактивен

 

#5 22.11.2013 13:14:55

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

"опция_2_3" выпадает потому, что выбрав комбинацию опция_1_1 параметра1 и опция_2_3 параметра2 мы полуим 0 товаров.
Запро вернет пустой результат:


SELECT COUNT(*) AS total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters AS pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('1')) #опция_1_1


AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('5')) #опция_2_3
GROUP BY `parameters_value_id`
 

Другие:опция_2_2,опция_2_4 не должны выпадать потому что они добавят результатов выборки.

Я хочу найти Все опции которые после выбора набора опций смогут найти больше 0-ля товаров. Мой запрос не находит всех а только те которые есть в наборе отфильтрованных товаров.

Это можно решить посылая 100+ запросов "сомнительных опций" на сервер проверяя вернет ли комбинация товары но это ужасный костыльный метод.

Отредактированно yuko (22.11.2013 13:27:09)

Неактивен

 

#6 22.11.2013 13:21:06

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

Неактивен

 

#7 22.11.2013 13:41:15

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

yuko написал:

"опция_2_3" выпадает потому, что выбрав комбинацию опция_1_1 параметра1 и опция_2_3 параметра2 мы полуим 0 товаров.

Т.е. вы хотите выбрать те опции, которые в сочетании с выбранной "опция_1_1" вернут ненулевое число товаров. Но тогда почему должна быть добавлена "опция_1_2" в результат. Ведь в комбинации с "опция_1_1" будет 0 товаров на представленных тестовых данных?

Неактивен

 

#8 22.11.2013 13:55:36

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

vasya написал:

yuko написал:

"опция_2_3" выпадает потому, что выбрав комбинацию опция_1_1 параметра1 и опция_2_3 параметра2 мы полуим 0 товаров.

Т.е. вы хотите выбрать те опции, которые в сочетании с выбранной "опция_1_1" вернут ненулевое число товаров. Но тогда почему должна быть добавлена "опция_1_2" в результат. Ведь в комбинации с "опция_1_1" будет 0 товаров на представленных тестовых данных?

Нет результат не вернет 0 а наоборот добавит товаров, опция _1_1 и 1_2 это опций одного параметра и они обрабатываются одним подзапросом exists как равносильные - конструкция or или in() - будут отобраны товары с опциями или опция _1_1 или опция _1_2 (каждый набор параметров в виде чекбоксов):


SELECT COUNT(*) AS total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters AS pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('1','2'))
GROUP BY `parameters_value_id`
 

Все опции одного параметра  обрабатываются через or,in а уже когда включаются опции другого параметра тогда подключается слудующая конструкция exixsts:

#-------------------Обработка опций второго параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv1`.`product_id` = `pv`.`product_id`
AND `pv1`.`parameters_value_id` IN ('6','4'))
 

Отредактированно yuko (22.11.2013 14:06:02)

Неактивен

 

#9 22.11.2013 14:01:55

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Дано: "опция_1_1"
Нужно выбрать все опции других параметров, которые в сочетании с "опция_1_1" дают отличное от нуля кол-во товаров + все опции того параметра к которому относится "опция_1_1"

Так?

Неактивен

 

#10 22.11.2013 14:09:54

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

vasya написал:

Дано: "опция_1_1"
Нужно выбрать все опции других параметров, которые в сочетании с "опция_1_1" дают отличное от нуля кол-во товаров + все опции того параметра к которому относится "опция_1_1"

Так?

Да  НО, не факт что 'все опции того параметра к которому относится "опция_1_1"', потому что в следующем наборе параметров можно выбрать опции которые также могут "заблокируют" часть опций первого параметра.

Выбрав только одну опцию должно быть как Вы написали:
Нужно выбрать все опции других параметров, которые в сочетании с "опция_1_1" дают отличное от нуля кол-во товаров + все опции того параметра к которому относится "опция_1_1"
Но если уже выбирать дальше опции других параметров, то эти опции могут отсеять часть опций предыдущего параметров

Отредактированно yuko (22.11.2013 14:12:19)

Неактивен

 

#11 22.11.2013 14:27:03

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Это как? После выбора "опция_1_1" у остальных параметров доступны только те опции, которые сочетаются с "опция_1_1" или нет?

Давайте так:
1) Фиксируем опцию одного параметра, например "опция_1_1", тогда мы должны выбрать те опции, которые ...

2) Фиксируем два параметра, например, "опция_1_1" + ..., тогда выбираем ...

Неактивен

 

#12 22.11.2013 14:32:32

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Правильно ли я понимаю, что если мы фиксируем 2 опции двух параметров, то должны выбрать те опции других параметров, которые в сочетании с 1 и 2 дают отличное от нуля кол-во товаров, а из опций параметров 1 и 2 остаются только выбранные ?

Неактивен

 

#13 22.11.2013 14:53:01

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Вот запрос для одной опции:

select distinct parameters_value_id from `products_parameters` where product_id in
(select product_id from  `products_parameters` where parameters_value_id=
(select id from `parameters_values` where `value`='опция_1_1'))
union
select id from `parameters_values` where parameter_id in
(select parameter_id from `parameters_values` where `value`='опция_1_1');


Для двух и более нужно уточнение, см предыдущий пост.

Неактивен

 

#14 22.11.2013 14:55:59

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

vasya написал:

Это как? После выбора "опция_1_1" у остальных параметров доступны только те опции, которые сочетаются с "опция_1_1" или нет?

Давайте так:
1) Фиксируем опцию одного параметра, например "опция_1_1", тогда мы должны выбрать те опции, которые ...

2) Фиксируем два параметра, например, "опция_1_1" + ..., тогда выбираем ...

1) Фиксируем опцию одного параметра, например "опция_1_1", тогда мы должны выбрать те опции, которые сочитаются с опция_1_1 других параметров а также все остальные опции первого параметра (которому пренадлежит опция_1_1)

2)Фиксируем два параметра, например, "опция_1_1" + "опция_2_1" (при этом опция_2_1 доступна для выбора так как она сочитается с опция_1_1 также незабываем что это опции разных параметров) тогда мы должны выбрать  опции которые сочитаются с опция_1_1 первого параметра и опция_2_1 второго параметра а также остальные опции второго параметра которые сочитаются с опция_1_1 первого параметра

3) Фиксируем 2 опции 1-го параметра  опция_1_1(230 товаров), опция_1_2 (120 товаров) получаем 350 товаров(для примера). Дальше во втором параметре нам допустимы опции которые сочитаются и с опция_1_1 и с опция_1_2. Например опция_2_1 сочитается с опция_1_1 а опция_2_2 сочитается с опцией_1_2. и Если  наш следующий выбор будет опция_2_1 то все товары опции_1_2 не покажутся а сама опция станет неактивной(заблокированной) но будет отмечена(на результат не повлеяет но если мы решим еще выбрать опция_2_2 то она опция_1_2 разблокируется)
Пример для понимания логики:
_http://filter.kombox.ru/tv/
Параметр частота обновления выбираем 200 и 400 Гц.
Дальше параметр Формат телевизора выбираем 21:9 - 400Гц заблокировалась. Дальше добавляем Формат 16:9 - 400Гц разблокировалась.
Вот такая логика зависимости.

Неактивен

 

#15 22.11.2013 15:14:45

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

Вопрос возможно глупый:


SELECT DISTINCT parameters_value_id FROM `products_parameters` WHERE product_id IN
(SELECT product_id FROM  `products_parameters` WHERE parameters_value_id=
(SELECT id FROM `parameters_values` WHERE `value`='опция_1_1'))
UNION
SELECT id FROM `parameters_values` WHERE parameter_id IN
(SELECT parameter_id FROM `parameters_values` WHERE `value`='опция_1_1')
 

А почему в выборке использубются названия атрибутов а не их ID? Разница явно есть потому что я пробовал ставить вместо названи - id (`value`='опция_1_1' => `id`=1) и у меня зависал запрос намертво - вот тут менял:

(SELECT parameter_id FROM `parameters_values` WHERE `value`='опция_1_1')
 

Неактивен

 

#16 22.11.2013 15:20:16

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Для двух и более параметров:

select distinct parameters_value_id from `products_parameters` where product_id in
(select product_id from  `products_parameters` where parameters_value_id in
(select id from `parameters_values` where `value` in ('опция_1_1')))
and
product_id in
(select product_id from  `products_parameters` where parameters_value_id in
(select id from `parameters_values` where `value` in ('опция_2_1')))
;

Неактивен

 

#17 22.11.2013 15:22:51

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

yuko написал:

Вопрос возможно глупый:


SELECT DISTINCT parameters_value_id FROM `products_parameters` WHERE product_id IN
(SELECT product_id FROM  `products_parameters` WHERE parameters_value_id=
(SELECT id FROM `parameters_values` WHERE `value`='опция_1_1'))
UNION
SELECT id FROM `parameters_values` WHERE parameter_id IN
(SELECT parameter_id FROM `parameters_values` WHERE `value`='опция_1_1')
 

А почему в выборке использубются названия атрибутов а не их ID? Разница явно есть потому что я пробовал ставить вместо названи - id (`value`='опция_1_1' => `id`=1) и у меня зависал запрос намертво - вот тут менял:

(SELECT parameter_id FROM `parameters_values` WHERE `value`='опция_1_1')
 

Можете заменить
WHERE parameters_value_id=
(SELECT id FROM `parameters_values` WHERE `value`='опция_1_1')
на
WHERE parameters_value_id=1

Использовал название, так как по условию задачи было дано "опция_1_1".

Неактивен

 

#18 22.11.2013 16:27:27

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать


select distinct parameters_value_id from `products_parameters` where product_id in
(select product_id from  `products_parameters` where parameters_value_id in
(select id from `parameters_values` where `value` in ('опция_1_1')))
and
product_id in
(select product_id from  `products_parameters` where parameters_value_id in
(select id from `parameters_values` where `value` in ('опция_2_1')))
;
 

Этот запрос дает тот же результат что и мой(остаются только фильтра которые соответсвуют отфильтрованным товарам):

SELECT COUNT(*) AS total, pv.parameters_value_id, parameters_values.value
FROM `products`  
JOIN products_parameters AS pv ON (`pv`.`product_id` = `products`.`id`)
JOIN `parameters_values` ON (`parameters_values`.`id` = `pv`.`parameters_value_id`)
WHERE `products`.`watch` = 1
#-------------------Обработка опций первого параметра
AND EXISTS (SELECT 1 FROM products_parameters pv0 WHERE `pv0`.`product_id` = `pv`.`product_id`
AND `pv0`.`parameters_value_id` IN ('1'))
#-------------------Обработка опций второго параметра
AND EXISTS (SELECT 1 FROM products_parameters pv1 WHERE `pv1`.`product_id` = `pv`.`product_id`
AND `pv1`.`parameters_value_id` IN ('3')) GROUP BY `parameters_value_id`
 

Проверял на живой базе

Отредактированно yuko (22.11.2013 16:29:57)

Неактивен

 

#19 23.11.2013 04:51:31

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

yuko написал:

2)Фиксируем два параметра, например, "опция_1_1" + "опция_2_1" (при этом опция_2_1 доступна для выбора так как она сочитается с опция_1_1 также незабываем что это опции разных параметров) тогда мы должны выбрать  опции которые сочитаются с опция_1_1 первого параметра и опция_2_1 второго параметра а также остальные опции второго параметра которые сочитаются с опция_1_1 первого параметра


select distinct parameters_value_id from `products_parameters` where product_id in
(select product_id from  `products_parameters` where parameters_value_id=1)
and product_id in (select product_id from  `products_parameters` where parameters_value_id=3)
-- опции, которые сочитаются с опция_1_1 первого параметра и опция_2_1 второго параметра (по сути ваш запрос)
union
-- добавляем остальные опции второго параметра, которые сочитаются с опция_1_1 первого параметра
select distinct parameters_value_id from `products_parameters` where product_id in
(select product_id from  `products_parameters` where parameters_value_id=1)
and parameter_id=2;
 

Неактивен

 

#20 23.11.2013 11:47:19

yuko
Участник
Зарегистрирован: 21.11.2013
Сообщений: 10

Re: Фильтрация фильтров помогите оптимизировать

Конкретно для второго параметра работает.
Нужно динамически это сделать чтоб для любого количество параметров работало. Запрос не доконца понял там если больше двух параметров то union-ы нужно добавлять или union один и в нем нужно ковырять?
Поток входящих опций


$str="";
foreach ($_GET["pr"] as $k => $one) {
foreach ($one as $key => $two) {
           $str.="sql code ";
}
}
$k //Id параметра
$two //Id опции
 

Объяснения как в $_GET сидят данные:
//$_GET[1][0]=1;$_GET[1][1]=2  - две опции(id=1,2) параметра с id=1
//$_GET[2][0]=3;$_GET[2][1]=4 -две опции(id=3,4) параметра с id=2
//$_GET[3][0]=5;$_GET[3][1]=6;$_GET[3][2]=7 -три опции(id=5,6,7) параметра с id=3

Отредактированно yuko (23.11.2013 11:58:15)

Неактивен

 

#21 23.11.2013 21:27:32

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Фильтрация фильтров помогите оптимизировать

Для N параметров:

-- добавляем остальные опции N-го параметра, которые сочитаются с опциями первых N-1 параметров
select distinct parameters_value_id from `products_parameters` where product_id in
(select product_id from  `products_parameters` where parameters_value_id in (id опций первых N-1 параметров))
and parameter_id=N;

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson