powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Выборка продуктов по свойствам
37 сообщений из 37, показаны все 2 страниц
Выборка продуктов по свойствам
    #38349569
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Задача: нужно вывести продукты по выбранным свойствам. Такое наверное встречали на каждом сайте, где присутствует фильтр.

Таблицы:

1) Продукты - собственно сами продукты.

Код: sql
1.
2.
3.
4.
5.
CREATE TABLE `test_products` (
  `p_id` int(11) NOT NULL AUTO_INCREMENT,
  `p_name` varchar(255) NOT NULL,
  PRIMARY KEY (`p_id`)
) AUTO_INCREMENT=1;




2) Имена свойств(к примеру "тип", "диагональ", "формат экрана").

Код: sql
1.
2.
3.
4.
5.
CREATE TABLE `test_feature_fields` (
  `ff_id` int(11) NOT NULL AUTO_INCREMENT,
  `ff_name` varchar(255) NOT NULL,
  PRIMARY KEY(`ff_id`)
) AUTO_INCREMENT=1;



3) Значения свойств(к примеру "жк-телевизор", "22", "16:9" соответственно).

`ff_id` - связка с test_feature_fields.ff_id

Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE `test_feature_values` (
  `fv_id` int(11) NOT NULL AUTO_INCREMENT,
  `fv_value` varchar(255) NOT NULL,
  `ff_id` int(11) NOT NULL,
  PRIMARY KEY(`fv_id`)
) AUTO_INCREMENT=1;



4) Сопоставления продуктов с парами свойство - значение свойства

p_id - связка с test_products.p_id
ff_id - связка с test_feature_fields.ff_id
fv_id - связка с test_feature_values.fv_id

Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE `test_product_features` (
  `pf_id` int(11) NOT NULL AUTO_INCREMENT,
  `p_id` int(11) NOT NULL,
  `ff_id` int(11) NOT NULL,
  `fv_id` int(11) NOT NULL
) AUTO_INCREMENT=1;




INSERT:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
INSERT INTO `ex`.`test_products` (`p_id` ,
`p_name` 
)
VALUES (NULL , 'Товар1'
), (NULL , 'Товар2'
);
INSERT INTO `ex`.`test_feature_fields` (`ff_id` ,
`ff_name` 
)
VALUES (NULL , 'Тип'
), (NULL , 'Цвет'
);
INSERT INTO `ex`.`test_feature_values` (`fv_id`, `fv_value`, `ff_id`) VALUES (NULL, 'Знач1', '1'), (NULL, 'Знач2', '1');
INSERT INTO `ex`.`test_feature_values` (`fv_id`, `fv_value`, `ff_id`) VALUES (NULL, 'Знач3', '2'), (NULL, 'Знач4', '2');
INSERT INTO `ex`.`test_product_features` (`pf_id` ,
`p_id` ,
`ff_id` ,
`fv_id` 
)
VALUES (NULL , '1', '1', '1'
), (NULL , '1', '2', '3'
);
INSERT INTO `ex`.`test_product_features` (`pf_id` ,
`p_id` ,
`ff_id` ,
`fv_id` 
)
VALUES (NULL , '2', '1', '2'
), (NULL , '2', '2', '4'
);



В данном примере допустим я выбираю продукт, у которого тип=знач1 и цвет=знач3 и должен вывести "товар1".
Много чего перепробовал, пробовал даже INTERSECT, который, прогуглив, нашёл у вас на форуме. Долго с ним мучался, а потом прочитал вверху форума SQLite :)
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349573
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNe,

1. Вставки (пакет ваших инсертов) - в боевом применении надо заворачивать в транзакцию. Это раз. Особенно, если учесть, что "юзверь" часто один - апач.

2. Посмотрите поиском в направлении EAV. Уже есть мноо примеров КАК выбирать и по одному и по набору параметров.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349678
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNe,

Сдуреешь от такой криптографии. Зачем вы сами себе жизнь портите? Без русского:

CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`val_id` int(11) NOT NULL default 1,
`product_name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);

CREATE TABLE `product_key` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key_name` varchar(255) NOT NULL,
PRIMARY KEY(`id`)
);

CREATE TABLE `product_val` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key_name_id` int(11) NOT NULL,
`val_name` varchar(255) NOT NULL,
PRIMARY KEY(`id`)
);

SELECT * FROM product, product_key, product_val where product_val.id = product.val_id AND product_key.id = product_val.key_name_id AND product.id = $something;

Не тестил, теоретически все должно получиться, потому что схема каноничная.

Получите кучу лишних полей, естественно, поскольку *.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349681
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Особенно впечатлил мост

`pf_id` int(11) NOT NULL AUTO_INCREMENT,
`p_id` int(11) NOT NULL,
`ff_id` int(11) NOT NULL,
`fv_id` int(11) NOT NULL

Юстас Алексу:
fftd, tder, desf,
psss, psfd, sjsf
....
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349687
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы потеряете время на расшифровке в стопицот раз больше чем сэкономите на набивке кода.

Я понимаю у многих с клавой нет дружбы, я и сам печатаю тремя с половиной пальцами, но опыт говорит что лучше назвать поле Наименование_Категории и Код_Наименования_Категории чем полчаса скрипеть мозгами и листать структуру чтобы найти n_cat или nm_cat_id
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349749
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
debloggerCREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`val_id` int(11) NOT NULL default 1,
`product_name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);

CREATE TABLE `product_key` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key_name` varchar(255) NOT NULL,
PRIMARY KEY(`id`)
);

CREATE TABLE `product_val` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key_name_id` int(11) NOT NULL,
`val_name` varchar(255) NOT NULL,
PRIMARY KEY(`id`)
);
Данный способ мне не подходит, так как values - конкретные значения, которые должны храниться в базе данных. Иначе мне придется на сайте в фильтре либо самому эти значения вручную вставлять для каждого свойства, либо выбирать из product_val distinct-ом `val_name`, что я считаю не есть хорошо.

debloggerОсобенно впечатлил мост

`pf_id` int(11) NOT NULL AUTO_INCREMENT,
`p_id` int(11) NOT NULL,
`ff_id` int(11) NOT NULL,
`fv_id` int(11) NOT NULL

Простите, я на самом деле немного подругому называю, просто хотел сократить названия полей, думал они будут интуитивно понятны, так как являются абревиатурами от F eature_ f ields(ff), F eature_ v alues(fv).
debloggerВы потеряете время на расшифровке в стопицот раз больше чем сэкономите на набивке кода.

Незнаю, я очень быстро привык, ну не все как я конечно..
debloggerЯ понимаю у многих с клавой нет дружбы, я и сам печатаю тремя с половиной пальцами, но опыт говорит что лучше назвать поле Наименование_Категории и Код_Наименования_Категории чем полчаса скрипеть мозгами и листать структуру чтобы найти n_cat или nm_cat_id

Не, я слепой печатник :)

Arhat109ExOLiNe,

1. Вставки (пакет ваших инсертов) - в боевом применении надо заворачивать в транзакцию. Это раз. Особенно, если учесть, что "юзверь" часто один - апач.

2. Посмотрите поиском в направлении EAV. Уже есть мноо примеров КАК выбирать и по одному и по набору параметров.
1. Учту, просто я до этого никогда не использовал транзакции.
2. Посмотрел. Сплошь везде только "альтернативы EAV", как будто этот способ самый худший :( Ну буду дальше искать. Однако буду очень рад помощи полезными ссылками, если у кого есть под рукой :)
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349754
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4) Сопоставления продуктов с парами свойство - значение свойства

p_id - связка с test_products.p_id
ff_id - связка с test_feature_fields.ff_id
fv_id - связка с test_feature_values.fv_id

CREATE TABLE `test_product_features` (
`pf_id` int(11) NOT NULL AUTO_INCREMENT,
`p_id` int(11) NOT NULL,
`ff_id` int(11) NOT NULL,
`fv_id` int(11) NOT NULL
) AUTO_INCREMENT=1;


Два поля лишние, должно быть только

`p_id` int(11) NOT NULL,
`fv_id` int(11) NOT NULL

и они должны быть в PK.

ff_id - есть уже в test_feature_values, а суррогатный ключ pf_id просто тут не нужен, он не будет использоваться.

Даже если ты оставишь эти поля, тебе нужно ещё добавить UNIQUE CONSTRAINT по продукту и свойству, иначе можно будет создавать несколько значений одного свойства.

Хотя ff_id можно и оставить, как раз для такого констрейнта.

Вот если бы в test_feature_values не было бы суррогатного ключа, а был бы составной из feature & value_id, можно было бы просто
сделать FK на составной PK в test_feature_values.

И я не понял, в чём вопрос собственно ?
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349757
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Обнаружил один способ, который работает:
Код: sql
1.
2.
3.
4.
SELECT * FROM `test_product_features` pf
LEFT JOIN `test_product_features` pff
ON pf.`p_id`=pff.`p_id`
WHERE pf.ff_id=1 && pf.fv_id=1 && pff.ff_id=2 && pff.fv_id=3


Это для двух свойств. SELECT'ом проходимся и выискиваем поля с одним значением поля, а LEFT JOIN'ом проходимся и находим поля со вторым значением, затем ON pf.`p_id`=pff.`p_id` выбирает только те продукты, у которых есть оба этих свойства.
Проблема:
Чем больше свойств - тем больше left-join'ов. Если выбранных свойств будет штук 50, то я думаю запрос будет выглядеть не очень красиво, не говоря уже о его производительности при постоянном перепросмотре всей таблицы.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349761
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Транзакции при вставках тут как раз ни на фиг не нужны.
Во-первых, не факт, что таблицы вообще транзакционные, а во-вторых, это скрипт инициализации бд, да ещё и тестовый.
Не надо там об этом думать.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349768
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNeОбнаружил один способ, который работает:

Проблема:
Чем больше свойств - тем больше left-join'ов. Если выбранных свойств будет штук 50, то я думаю запрос будет выглядеть не очень красиво, не говоря уже о его производительности при постоянном перепросмотре всей таблицы.


Это НЕ проблема. Хоть 200 JOIN-ов.
Про производительность поговорим тогда, когда ты покажешь конкретный запрос с конкретным планом и с конкретными тормозами.

Ну и надо сказать, некоторые предпосылки такой "плохой производительности" у тебя уже есть в дизайне твоей БД, так что либо переделывай структуру, либо не ной и пиши и оптимизируй запросы.

Запрос у тебя не совсем правильный, он должен выбирать продукты , а JOIN-ить каждое свойство.
JOIN НЕ МОЖЕТ быть OUTER, поскольку это фильтр по AND.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349783
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv4) Сопоставления продуктов с парами свойство - значение свойства

p_id - связка с test_products.p_id
ff_id - связка с test_feature_fields.ff_id
fv_id - связка с test_feature_values.fv_id

CREATE TABLE `test_product_features` (
`pf_id` int(11) NOT NULL AUTO_INCREMENT,
`p_id` int(11) NOT NULL,
`ff_id` int(11) NOT NULL,
`fv_id` int(11) NOT NULL
) AUTO_INCREMENT=1;


Два поля лишние, должно быть только

`p_id` int(11) NOT NULL,
`fv_id` int(11) NOT NULL

и они должны быть в PK.

ff_id - есть уже в test_feature_values, а суррогатный ключ pf_id просто тут не нужен, он не будет использоваться.

Даже если ты оставишь эти поля, тебе нужно ещё добавить UNIQUE CONSTRAINT по продукту и свойству, иначе можно будет создавать несколько значений одного свойства.

Хотя ff_id можно и оставить, как раз для такого констрейнта.

Вот если бы в test_feature_values не было бы суррогатного ключа, а был бы составной из feature & value_id, можно было бы просто
сделать FK на составной PK в test_feature_values.

И я не понял, в чём вопрос собственно ?
Нет, я просто не стал сюда писать что у меня составной ключ на (p_id, ff_id), я посчитал это не нужным. Суррогатный ключ уберу, ок. Просто привык уже к каждой таблице привязывать авто_инкремент, плохая привычка.
Вопрос собственно: как составить оптимальный запрос на выборку продуктов с неограниченным количеством выбранных свойств?
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349874
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
from `test_products` p
where p.`p_id` in (
   select pf.`p_id`--, ff.`ff_name`,fv.`fv_value`
   from `test_feature_fields` ff
   join `test_feature_values` fv on fv.`ff_id`=ff.`ff_id`
   join `test_product_features` pf on pf.`fv_id`=fv.`fv_id`
   where (ff.`ff_name`,fv.`fv_value`) in (('Тип','Знач1'),('Цвет','Знач3'))
   )
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349935
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cygapb-007так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
from `test_products` p
where p.`p_id` in (
   select pf.`p_id`--, ff.`ff_name`,fv.`fv_value`
   from `test_feature_fields` ff
   join `test_feature_values` fv on fv.`ff_id`=ff.`ff_id`
   join `test_product_features` pf on pf.`fv_id`=fv.`fv_id`
   where (ff.`ff_name`,fv.`fv_value`) in (('Тип','Знач1'),('Цвет','Знач3'))
   )


Нет. При выборе пары(ff_id-fv_id) 1-2, 2-3 выводит два товара, хотя должен вернуть NULL
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349940
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуглить "фасетный поиск"
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38349941
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вроде бы нашел решение:

Код: sql
1.
2.
3.
4.
5.
6.
SELECT CASE WHEN COUNT( p_id ) =2
THEN p_id
END FROM `test_product_features` 
WHERE (ff_id =1 && fv_id =1
) || ( ff_id =2 && fv_id =3 ) 
GROUP BY p_id



Производится поиск по таблице-связке всех возможных совпадений через ИЛИ. Потом полученные строки группируются по p_id и подсчитывается количество p_id из результата. Если count(p_id) равен количеству запрашиваемых из базы свойств - значит у продукта есть все запрашиваемые свойства. Но это конечно только подзапрос, но самый важный.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350085
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNeДанный способ мне не подходит, так как values - конкретные значения, которые должны храниться в базе данных. Иначе мне придется на сайте в фильтре либо самому эти значения вручную вставлять для каждого свойства, либо выбирать из product_val distinct-ом `val_name`, что я считаю не есть хорошо.

Ваш клиент не умеет редактировать рекордсеты или вы о чем вообще пишите?

Сделайте своего клиента который разберется в матерях-дочках или как там, в InnoDB fk профтыкайте ради integrity. Даже VIEW's можно сделать редактируемым, а тут понимаешь полтора справочника и уже проблемы.

Все что хранится в базе имеет конкретные значения если база нормальная. Если ненормальная, то зачем база, для этого есть екзель.

Короче при чем тут дистинкт и все такое я не понял. Вы можете сделать так чтобы когда основная табля загрузилась в одминку, все связанные справочники выкатились бы списками. Можно и инлайн сделать, но проще на странице редактирования/добавления записи.

По-моему это обыкновенно уже давно.

Тогда вам ничего ручками вводить не придется, а самая мякотка в том, что в сущности у вас всегда одна таблица с записями которой можно делать что хочешь.

Это для отчетов требуются сложные взаимосвязи, а для оперативного управления все должно быть простым как карандаш, иначе оно грохнется от самого управления не дожидаясь пользования.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350100
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще, следите за смыслом. Неотъемлимые свойства "отъемлять" не надо. Особенно когда они один фиг - числа. За каким выносить диагонали, диаметры и длину члена в справочник?

Я понимаю, чтобы тетка не вписала 17 км, в поле где должно быть 17 дюймов. Но знаете дело в чем - вы все равно не сможете сделать так, чтобы тетка не вписала Поносоник.

Кто-то же когда-то же должен завести такую запись в справочнике. Правильно? Если этот кто-то идиот - никакой самый расчудесный клиент ему не поможет. Ну, если только есть некая мировая БД по телеящикам откуда можно взять правЕльное наименование...

Это древняя проблема культуры ведения БД в целом, а наша проблема в том что мы теряем грамотность катастрофически.

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

Короче это неколебимо. Одни борются с другими, а в целом все вместе идут ко дну.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350101
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
debloggerВаш клиент не умеет редактировать рекордсеты или вы о чем вообще пишите?

Как раз таки о том и речь, чтобы клиент мог свободно добавлять/удалять/редактировать values, чтобы они потом по всему сайту где это требуется выпадали списком. А когда значения хранятся как просто строковые, без привязки id - мне кажется тогда уж можно вобще всё упростить до одного текстового поля description, а фильтр тогда сделать просто LIKE '%что-то%'

debloggerСделайте своего клиента который разберется в матерях-дочках или как там, в InnoDB fk профтыкайте ради integrity. Даже VIEW's можно сделать редактируемым, а тут понимаешь полтора справочника и уже проблемы.
Про VIEW почитаю.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350105
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Знаете как проектируется идеальная БД и идеальный клиент? Вот так:

Внес оператор повторую запись - штраф 1000 р
Внес оператор запись с идиоткой ошибкой - штраф 3000 р

Через неделю база будет сиять.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350111
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, конечно, придется сперва платить хорошо. А у нас же все наоборот. Надо набрать идиотов за копейки, которых и штрафовать смысла нет - у него получка на три ошибки. Ну и потом ищутся такие специалисты которые могут сделать идиото-устойчивую БД с клиентом. Получается же все равно гавно. Потому что начальные условия таковы.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350119
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot ExOLiNe]debloggerА когда значения хранятся как просто строковые, без привязки id

А, понятно, без своей криптографии вы уже не понимаете написанное человеческим языком.

У меня не было таких полей - все справочники связаны через identity с таблей товаров.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350124
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или не увидев священных иннер джойнов вы даже и смотреть в табли не стали? :)

Ну, да, а как же без них. Ну сделайте на явных джойнах. Нужны нулы - на лефтах.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350160
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNeНет. При выборе пары(ff_id-fv_id) 1-2, 2-3 выводит два товара, хотя должен вернуть NULLгы...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select * 
from `test_products` p
where p.`p_id` in (
   select pf.`p_id`
   from `test_feature_fields` ff
   join `test_feature_values` fv on fv.`ff_id`=ff.`ff_id`
   join `test_product_features` pf on pf.`fv_id`=fv.`fv_id`
   where (ff.`ff_name`,fv.`fv_value`) in (('Тип','Знач1'),('Цвет','Знач3'))
   group by pf.`p_id`
   having COUNT(*)=2
   )
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350483
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNeВопрос собственно: как составить оптимальный запрос на выборку продуктов с неограниченным количеством выбранных свойств?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select *
from products p
join product_features pf1 on pf1.p_id = p.p_id 
      join feature_values pfv1 on pfv1.fv_id = pf1.fv_id and pf1.ff_id = ( select ff_id from feature_fields where ff_name = :prop1_name) and pfv1.fv_value = :prop1_value

join product_features pf2 on pf2.p_id = p.p_id 
      join feature_values pfv2 on pfv2.fv_id = pf2.fv_id and pf2.ff_id = ( select ff_id from feature_fields where ff_name = :prop2_name) and pfv2.fv_value = :prop2_value

--  и так далее ...
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350487
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ExOLiNeВроде бы нашел решение:

Код: sql
1.
2.
3.
4.
5.
6.
SELECT CASE WHEN COUNT( p_id ) =2
THEN p_id
END FROM `test_product_features` 
WHERE (ff_id =1 && fv_id =1
) || ( ff_id =2 && fv_id =3 ) 
GROUP BY p_id



Производится поиск по таблице-связке всех возможных совпадений через ИЛИ. Потом полученные строки группируются по p_id и подсчитывается количество p_id из результата. Если count(p_id) равен количеству запрашиваемых из базы свойств - значит у продукта есть все запрашиваемые свойства. Но это конечно только подзапрос, но самый важный.

Это неверный ответ. В смысле, запрос.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350489
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто НЕ проблема. Хоть 200 JOIN-ов.Увы, максимум 61.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350492
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
debloggerИ еще, следите за смыслом. Неотъемлимые свойства "отъемлять" не надо. Особенно когда они один фиг - числа. За каким выносить диагонали, диаметры и длину члена в справочник?.

Блин, ну надо ему.

Вполне логично в некоторых областях. НАпример, покрышки -- они не бывают произвольных размеров, логично завести все их предопределённые размеры в справочник.

Конечно, не все свойства имеют такие ограничения, это я согласен. Но это уж пусть автор сам решает.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350493
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftMasterZivЭто НЕ проблема. Хоть 200 JOIN-ов.Увы, максимум 61.

Ну, ок, значит 20 или 30 свойств можем задать в фильтре, не так и мало.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350580
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

Покрышки связаны непосредственно с дисками и вторично с характеристиками автомобиля как то масса, скорость. Диски связаны со ступицей, ступица связана с подвеской, подвеска связана с кузовом и так далее и чтобы вывести весь этот bill of material нам тут жизни не хватит.

С чем интересно связана диагональ телевизора? С аквариумом, да? :)

В первом случае у нас реляционная бд во всей красе, во втором извращение. Premature optimization, короче. Вместо того, чтобы подумать как упростить, автор начитавшись предисловий начал дробить индивидуальность и сам себя загоняет в подполье.

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

И вообще, кто ж автору мешает проиндексировать эти диагонали из живых данных и вывести оглавление списком? В том числе той тетки - чтобы выбирала ближайшее значение, если совсем тупая.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350585
deblogger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот если бы для телевизоров продавались глицериновые линзы как это было в прошлом, тогда я понимаю - пришлось бы сводить диагонали линз и экранов. Но и тогда можно было бы живо подобрать линзу под ящик задав порог отклонения (threshold) запрашивая данные прямо из таблей ТВ и ЛИНЗА.

Ну допустим применительно к анальным покрышкам для телефонов это справедливо. Но там же нет строгих критериев. Длина-ширина подходит - значит мое. Достаточно обмерить все телефоны и сравнить с тем какие есть размеры пленочек для экранов.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350665
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
deblogger...

Ты вот сейчас с кем разговаривал ?
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38350987
ExOLiNe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivExOLiNeВроде бы нашел решение:

Код: sql
1.
2.
3.
4.
5.
6.
SELECT CASE WHEN COUNT( p_id ) =2
THEN p_id
END FROM `test_product_features` 
WHERE (ff_id =1 && fv_id =1
) || ( ff_id =2 && fv_id =3 ) 
GROUP BY p_id



Производится поиск по таблице-связке всех возможных совпадений через ИЛИ. Потом полученные строки группируются по p_id и подсчитывается количество p_id из результата. Если count(p_id) равен количеству запрашиваемых из базы свойств - значит у продукта есть все запрашиваемые свойства. Но это конечно только подзапрос, но самый важный.

Это неверный ответ. В смысле, запрос.
Можно хотя бы аргументировать?
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38351000
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Автору:

ExOLiNeCygapb-007так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
from `test_products` p
where p.`p_id` in (
   select pf.`p_id`--, ff.`ff_name`,fv.`fv_value`
   from `test_feature_fields` ff
   join `test_feature_values` fv on fv.`ff_id`=ff.`ff_id`
   join `test_product_features` pf on pf.`fv_id`=fv.`fv_id`
   where (ff.`ff_name`,fv.`fv_value`) in (('Тип','Знач1'),('Цвет','Знач3'))
   )


Нет. При выборе пары(ff_id-fv_id) 1-2, 2-3 выводит два товара, хотя должен вернуть NULL

Я бы продолжил разработку этого варианта. Он не совсем верный, но "движется в правильном направлении". В смысле, НЕ требует 100-500 джойнов. Не вижу проблем его переработать. Он просто отдаст любые найденные пары (IN == или), а вам надо чтобы были все ( == и). Внутренний подзапрос неплохо сгруппировать и подсчитать количество совпадений для каждого продукта.

Ну и ещё, у себя, такое чудо перерабатывал в джойны вместо подзапроса в качестве условия. Вроде пошустрее, но сильно -не тестил.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38351001
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow,

причём тут "фасетный поиск", развенёте свою мысль или оставите "как есть"? :)
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38351017
=)8)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arhat109Автору:

ExOLiNeпропущено...

Нет. При выборе пары(ff_id-fv_id) 1-2, 2-3 выводит два товара, хотя должен вернуть NULL

Я бы продолжил разработку этого варианта. Он не совсем верный, но "движется в правильном направлении". В смысле, НЕ требует 100-500 джойнов. Не вижу проблем его переработать. Он просто отдаст любые найденные пары (IN == или), а вам надо чтобы были все ( == и). Внутренний подзапрос неплохо сгруппировать и подсчитать количество совпадений для каждого продукта.

Ну и ещё, у себя, такое чудо перерабатывал в джойны вместо подзапроса в качестве условия. Вроде пошустрее, но сильно -не тестил.Уже было предложено ( 14642792 ), но там тоже начнутся проблемы при выборе из однотипных значений (например, белого или серого цветов)
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38351130
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=)8),

ну дык. Не только же COUNT() является "критерием"... можно и поаккуратнее фильтровать.
...
Рейтинг: 0 / 0
Выборка продуктов по свойствам
    #38351228
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=)8)там тоже начнутся проблемы при выборе из однотипных значений (например, белого или серого цветов)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
drop table if exists `test_user_selected`;
CREATE TABLE `test_user_selected` (
  `us_name` varchar(255) NOT NULL,
  `us_value` varchar(255) NOT NULL
) DEFAULT CHARSET=utf8;
insert into `test_user_selected` values
  ('Тип','Знач1'),
  ('Цвет','Знач3'),
  ('Цвет','Знач4');

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
set @qty:=(select count(distinct us_name) from test_user_selected);

select *
from test_products p
where p.p_id in (
  select pf.p_id
  from(
    select pf.p_id, ff.ff_id
    from test_user_selected us
    join test_feature_fields ff on ff.ff_name=us.us_name
    join test_feature_values fv on fv.fv_value=us.us_value
    join test_product_features pf on pf.fv_id=fv.fv_id
    group by  pf.p_id, ff.ff_id
    ) pf
  group by  pf.p_id
  having count(*)=@qty
  )

sqlfiddle.com
Еще проще (не потребуются дополнительные индексы), если в таблицу пользовательского выбора записывать ID а не текст
...
Рейтинг: 0 / 0
37 сообщений из 37, показаны все 2 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Выборка продуктов по свойствам
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]