Гость
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам / 25 сообщений из 29, страница 1 из 2
18.07.2013, 18:11
    #38336073
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Есть следующие таблицы в БД. БД вида "продукт - свойства"

#######
#Product#
#######

ID PRIMARY KEY INT UNIQUE
name VARCHAR(255)
description VARCHAR(255)

########
#property#
########

ID INT PRIMARY KEY UNIQUE
product_id INT FOREIGN KEY (Product)
name VARCHAR(255)
value VARCHAR(255)

Хочу выполнить примерно следующий запрос: "Выбрать все продукты со всеми свойствами. Условие: Значение определенного свойства (value) = 'текст' ".
Не могу сконструировать запрос, ничего путевого кроме WHERE id IN() не приходит.
Таблицы предполагаются: product ~ 20 000 записей
property примерно на порядок больше

Код: sql
1.
SELECT property.product_id AS p_id FROM property AS pr WHERE  (pr.name='цвет' AND pr.value = 'красный')


Только одно условие для поиска

Код: sql
1.
SELECT prod.name, prop.value FROM product AS prod JOIN property AS prop ON prop.product_id = prod.id


Вернет мне список всех продуктов со всеми свойствами (я надеюсь :) ), но не понятно как дальше с ним поступать.

Как выбрать продукты со всеми свойствами, у которого заданы определенные значение свойств?
...
Рейтинг: 0 / 0
18.07.2013, 19:36
    #38336158
pit_alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest man,

Что мешает во второй запрос добавить условие WHERE и нужные поля?
...
Рейтинг: 0 / 0
18.07.2013, 20:40
    #38336198
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
pit_alex,

На один товар приходится множество свойств. При добавлении WHERE будет выбран продукт с одним свойством, а не со всеми
...
Рейтинг: 0 / 0
18.07.2013, 20:52
    #38336204
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest manpit_alex,

На один товар приходится множество свойств. При добавлении WHERE будет выбран продукт с одним свойством, а не со всемиТогда убери where.
...
Рейтинг: 0 / 0
18.07.2013, 20:56
    #38336205
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
White Owl,

Тогда как сделать выборку товаров со свойствами при условии что одно(несколько) свойств равно x,y,z...?

P.S. WHERE предложил не я
...
Рейтинг: 0 / 0
18.07.2013, 21:05
    #38336210
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Прочитай: 13467826
Оформи свои желания в соответствии с этой инструкцией и тогда мы поймем чего-же ты хочешь.
...
Рейтинг: 0 / 0
18.07.2013, 22:02
    #38336228
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
White Owl,
Благодарю за ман.

1) Убеждаюсь что я работаю с базой данных типа SQLite. Наличие другой базы данных исключено - увы

2) Пишу и публикую скрипт, создающий тестовые таблицы. Убедился в их работоспособности
Код: 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.
create table prod (
  id integer primary key autoincrement,
  name varchar
);

create table prop (
  id integer primary key autoincrement,
  prod_id   integer,
  name varchar,
  value varchar,
  foreign key(prod_id) references prod(id)
);

insert into prod (name) values ('hat');
insert into prod (name) values ('t-shirt');
insert into prod (name) values ('gloves');

insert into prop (prod_id, name, value) values (1, 'color' ,'red');
insert into prop (prod_id, name, value) values (1, 'material' ,'whool');
insert into prop (prod_id, name, value) values (1, 'condition', 'new');
insert into prop (prod_id, name, value) values (2, 'condition', 'new');
insert into prop (prod_id, name, value) values (2, 'size', 'xxl');
insert into prop (prod_id, name, value) values (2, 'material', 'cotton');
insert into prop (prod_id, name, value) values (3, 'condition', 'old');



3) Хочу получать товары (например hat и t-shirt) со всеми его свойствами (new, whool, red, xxl, new) используя при поиске значения свойств. Например так (prop.name = 'condition' and prop.value = 'new')
или лучше даже так (prop.name = 'condition' and prop.value = 'new') and (prop.name='size' and prop.value='xxl')

4) Хочу на выходе иметь:

для prop.name = 'condition' and prop.value = 'new'

id prod_name prop_name value1 hat color red1 hat material whool1 hat condition new2 t-shirt condition new2 t-shirt size xxl2 t-shirt material cotton

для (prop.name = 'condition' and prop.value = 'new') and (prop.name='size' and prop.value='xxl')

id prod_name prop_name value2 t-shirt condition new2 t-shirt size xxl2 t-shirt material cotton

5) Убеждаюсь что текстовое описание результата (из пункта 3) совпадает с результатом который я привел в пункте 4. Между текстом и примером не наблюдаю расхождений. Жду помощи, а не много вопросов на тему: "а ты сам знаешь что ты хочешь?"

6) Пытаюсь:

Код: sql
1.
2.
SELECT prod.id, prod.name AS prod_name, prop.name AS prop_name, prop.value AS value FROM prod 
           JOIN prop ON prod.id = prop.prod_id WHERE (prop.name = 'condition' AND prop.value = 'new')



Ожидаемо получаю результат
id prod_name prop_name value1 hat condition new2 t-shirt condition new
Просто никаких идей с какой стороны за это взяться

Спасибо, надеюсь на вашу помощь
...
Рейтинг: 0 / 0
18.07.2013, 22:24
    #38336238
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest man, джойнуть prod к prop (а не наоборот, как сейчас)?
...
Рейтинг: 0 / 0
18.07.2013, 22:48
    #38336248
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
фигню какую-то написал))
ты хочешь результаты master+detail датасета запихнуть в 1 выборку, продублировав master'а
мне пока тоже пришел в голову или вариант where id in (), или вот такой маразм))
Код: sql
1.
2.
3.
select * from prod p 
join prop on p.id=prop.prod_id
where exists(select * from prop tmp where tmp.name='condition' and tmp.value='new' and tmp.prod_id=p.id)

интересно, какой из запросов быстрее отработает))
...
Рейтинг: 0 / 0
18.07.2013, 22:53
    #38336255
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
или даже так
Код: sql
1.
2.
3.
select * from prod p 
join (select prod_id from prop tmp where tmp.name='condition' and tmp.value='new') ids on p.id=ids.prod_id
join prop on p.id=prop.prod_id
...
Рейтинг: 0 / 0
19.07.2013, 02:59
    #38336324
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Ну а для набора атрибутов можно сделать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
sqlite> select prod.id, prod.name, prop.name, prop.value from prod
   ...> join prop on prod.id=prop.prod_id
   ...> join (
   ...>      select prod_id from prop where prop.name = 'condition' and prop.value = 'new'
   ...>      intersect
   ...>      select prod_id from prop where prop.name = 'size' and prop.value = 'xxl'
   ...> ) ids 
   ...>      on ids.prod_id=prod.id;
2|t-shirt|condition|new
2|t-shirt|size|xxl
2|t-shirt|material|cotton
sqlite> 
...
Рейтинг: 0 / 0
19.07.2013, 10:04
    #38336455
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
White Owl, fd00ch

Спасибо вам большое, очень помогли. Я сам как-то позабыл что join объединяет только те строки у которых есть соответствие и слева и справа. А последовательно JOINы работают как AND условие.

Я немного модифицировал запрос, что скажете?

авторsqlite> select prod.id, prod.name, prop.name, prop.value from prod
...> join (
...> select prod_id from prop where prop.name = 'condition' and prop.value = 'new'
...> intersect
...> select prod_id from prop where prop.name = 'size' and prop.value = 'xxl'
...> ) ids
...> on ids.prod_id=prod.id
...> join prop on prod.id=prop.prod_id;
2|t-shirt|condition|new
2|t-shirt|material|cotton
2|t-shirt|size|xxl


мне показалось, что сперва лучше отфильтровать продукты, чтобы не JOINить все продукты с атрибутами (я так предполагаю, план запроса я не смотрел, каюсь), а потом к ним JOIN их свойств.
Исправьте если не прав. Еще раз спасибо
...
Рейтинг: 0 / 0
19.07.2013, 12:00
    #38336678
AIS
AIS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest man ,
а Вам не кажется, что лучше иметь три таблицы, а не две?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create table prod (
  id integer primary key autoincrement,
  name varchar
);

create table prop (
  id integer primary key autoincrement,
  name varchar
);

create table prod-prop (
  id integer primary key autoincrement,
  prod_id   integer,
  prop_id   integer,
  value-prop varchar,
  foreign key(prod_id) references prod(id),
  foreign key(prop_id) references prop(id)
);


такая нормализация не помешает и можно получать всё, что захочешь ;)
...
Рейтинг: 0 / 0
19.07.2013, 12:38
    #38336754
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
AIS,

Бррр, поясните как получать то, что я захочу?
Пока чего-то в ступоре
...
Рейтинг: 0 / 0
19.07.2013, 12:49
    #38336776
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
AIS, тогда уж вводить таблицы prod, prop-name, prop-value, prod-prop :о)

Guest man, выборка делается так же, только джойнов поболее
а по порядку указывания таблиц - мне казалось, выгоднее мелкие таблицы джойнить первыми, а крупные - последними; или же сначала джойнить по индексу, а в конце - через fullscan (хотя оптимизатор все равно будет работать и может изменить логику). если у тебя есть тестовые данные - можешь попробовать сделать замеры с разным порядком таблиц
...
Рейтинг: 0 / 0
19.07.2013, 12:53
    #38336788
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
AIS,

Код: sql
1.
2.
3.
select prod.*, prop.name, prop-value from prod-prop pp
join prod on prod.id = pp.prod_id
join prop on prop.id = pp.prop_id and (prop.name = 'size' and pp.prop-value = 'xxl') and (prop.name = 'condition' and pp.prop-value = 'new')



Если не ошибаюсь, это вернет то, что нужно мне...
...
Рейтинг: 0 / 0
19.07.2013, 13:06
    #38336822
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
fd00ch,

Тестовые данные есть. Так в том то и дело, что продуктов меньше чем их свойств (на каждый продукт приходится по 15-16 атрибутов)

и делая join (
...> select prod_id from prop where prop.name = 'condition' and prop.value = 'new'
...> intersect
...> select prod_id from prop where prop.name = 'size' and prop.value = 'xxl'
...> ) ids
...> on ids.prod_id=prod.id;
мы таким образом выбираем id только интересных нам продуктов, а потом к ним по индексу join наших свойств.

Тестовая выборка prod ~ 300 шт.
prop ~ 5500 шт.
Время запросов что-то около 0.004s AMD E-350 1.6ghz 2gb

У меня вообще другая идея пришла
Код: sql
1.
2.
3.
   create view prod_prop as 
   select prod.*, prop.name, prop.value from prod
       join prop on prop.prod_id = prod.id



Код: sql
1.
2.
    select * from prod_prop 
    join prod_prop pp on prod_prop.id = pp.id and (pp.name = 'size' and pp.value = 'xxl') and (pp.name = 'condition' and pp.value = 'new')



Еще не прогнал в sqlite3, но думаю что заработает
...
Рейтинг: 0 / 0
19.07.2013, 13:19
    #38336848
AIS
AIS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
fd00chAIS, тогда уж вводить таблицы prod, prop-name, prop-value, prod-prop :о)

Если prop-value имеют какие-то определенные, ограниченные по количеству варианты значений и встречаются в разных prop, то лучше так и сделать.
А если prop-value это беспорядочные значения, которые по колизии могут конечно быть одинаковыми в разных prop, но не более, то эти список таблиц мягко говоря избыточный.

Guest manБррр, поясните как получать то, что я захочу?
Вы не знаете как в моем варианте БД вывести все свойства для продукта с опредленным ID?
...
Рейтинг: 0 / 0
19.07.2013, 13:32
    #38336875
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
AIS,

Можно на Ты.
Нет, я не могу сообразить пока как при такой схеме ввести ограничения на атрибуты (name='condition', value='new'; name = 'size', value = 'xxl'), но я так понял будет также как и при 2х таблицах

А select будет такой же, только появится дополнительный join
...
Рейтинг: 0 / 0
19.07.2013, 13:49
    #38336925
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Конечно же не работает


Код: sql
1.
2.
3.
4.
   
create view prod_prop as 
   select prod.*, prop.name as p_name, prop.value from prod
       join prop on prop.prod_id = prod.id



От подзапросов и intersect видимо не уйти :(

Код: sql
1.
2.
3.
4.
5.
6.
7.
    select * from prod_prop 
    join (
           select id from prod_prop WHERE (prod_prop.p_name = 'size' and prod_prop.value = 'xxl') 
           intersect
           select id from prod_prop WHERE (prod_prop.p_name = 'condition' and prod_prop.value = 'new')
    ) ids
          on ids.id = prod_prop.id



Скажите, пожалуйста, есть ли альтернативный способ организации базы, чтобы упростить поиск?
Я прошу прощения за свою глупость, но осуждайте грех, а не грешника
...
Рейтинг: 0 / 0
19.07.2013, 13:59
    #38336944
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest manСкажите, пожалуйста, есть ли альтернативный способ организации базы, чтобы упростить поиск?поиск и так несложный, че ты его упрощать вздумал?
а по организации - скорее всего, подойдет вариант, о котором я писал выше - еще большее разбиение. т.к. у реальных товаров свойства или находятся в ограниченном списке (для строк), или в ограниченном диапазоне значений (для чисел). можно в таблицу prop-name добавить столбец prop_type, где хранить тип свойства (integer/float/string), а в таблицу prop-value пихать значения, невзирая на тип столбца value (благо, sqlite это позволяет). такая организация позволит сделать удобные и быстрые фильтры в будущем, как на Яндекс.Маркете
а в таблицу prod-prop добавить столбец index, чтобы все свойства товара выводить в нужном порядке (или даже несколько столбцов для организации дерева свойств, как на том же Маркете)
...
Рейтинг: 0 / 0
19.07.2013, 14:27
    #38337026
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
fd00ch,

Если говорить о реальном приложении, то у меня организовано следующим образом

Код: 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.
create table prod (
  id integer primary key autoincrement,
  header varchar,
  desc varchar
); 

create table prop (
  id integer primary key autoincrement,
  prod_id integer,
  dict_id integer,
  value varchar,
  float_value float,

  foreign key(prod_id) references prod(id),
  foreign key(dict_id) references dict(id)
);

create table dict (
  id integer primary key autoincrement,
  name varchar,
  rus_name varchar,
  type varchar,
  units varchar,
  sorting integer
);
...
Рейтинг: 0 / 0
19.07.2013, 14:53
    #38337075
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest man, от задачи все зависит

ты планируешь сделать фильтры товаров по свойствам, где будут использоваться списки всех значений с множественным выбором или ползунки - для чисел (как в Маркете)? плюс, отображение "на лету" числа товаров, которые остались после применения фильтров

если да - то твоя схема - говно :о) о чем будут намекать постоянные distinct'ы при построении вышеупомянутых списков всех значений + необходимость индексировать строковый столбец в большой таблице prop (чтобы distinct работал быстро, да и последующий where). вместо использования небольших таблиц-справочников и быстрого соотношения pk-fk

если даже в голубых мечтах такая интерактивность не грозит - твоя схема сойдет, легче ж запросы писать)) если других схожих "примочек" не будет, конечно
...
Рейтинг: 0 / 0
19.07.2013, 15:33
    #38337149
Guest man
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
fd00ch,

Да, спасибо большое. Очень ценю искренность и прямоту в людях.
Я понимаю что схема говно, с этим даже спорить трудно :)

Я пока не большой специалист в этом, но не ошибается тот кто ничего не делает. Буду учиться.
Действительно, я не учел того что pk-fk быстрое соотношение и я бы мог
Код: sql
1.
select prop_key from prop_name pn where pn.name = 'material'


А потом по быстрому в таблицах шарить + join's

Но в какой-то мере это legacy код. За ошибки молодости...
Да простит меня SQL бог.

Еще раз всем спасибо. Стало намного яснее. Очень давно не занимался sql. Еще раз простите.
...
Рейтинг: 0 / 0
19.07.2013, 15:53
    #38337181
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам
Guest manЯ понимаю что схема говно, с этим даже спорить трудно :)ключевая мысль пред.поста - от задачи все зависит. которую тут никто, кроме тебя, не знает
...
Рейтинг: 0 / 0
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Отношение типа "продукт-свойства". Выборка продукты+все свойства + условия на свойствам / 25 сообщений из 29, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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