Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
Нужна помощь уважаемого сообщества

Есть две таблицы.
В одной хранятся девайся, в другой их параметры

Таблица1
(
id uniqeidentifier,
name varchar(127)
)
Таблица2
(
id uniqeidentifier,
nodeid uniqeidentifier --(FK->таблица1->id),
param varchar(127),
value varchar(127)
)

У каждого девайся от 2 до 16 параметров.
Подскажите, пожалуйста, как сделать наиболее эффективный подбор девайсов по параметрам.

Делал через несколько Exists, но это слишком медленно.

Спасибо
21 сен 04, 15:39    [975912]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37101
А что такое "подбор девайсов по параметрам"?
21 сен 04, 15:40    [975929]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
Гавриленко Сергей Алексеевич
А что такое "подбор девайсов по параметрам"?


Нужно выбрать из Таблицы1 элементы, для которых существуют записи в Таблице2, например

Select A.ID, A.Name FROM Таблица1 A
where
EXISTS
(
SELECT * FROM Таблица2 B
WHERE B.nodeid = A.id
AND B.param='key' and B.value="value"
)
21 сен 04, 15:47    [975964]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Breakneck
Member

Откуда: Kiev
Сообщений: 2454
Делаем отдельную табличку с критериями поиска - параметрами и затем дополнительный join:

create table #t3
(param varchar(127),
value varchar(127))

select * from t1 
inner join t2 on (t1.id=t2.nodeid)
inner join #t3 on (t2.param=#t3.param)
where t2.Value = #t3.value
21 сен 04, 15:50    [975990]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
SergeyPl
Member

Откуда: Харьков
Сообщений: 287
Select A.ID, A.Name FROM Таблица1 A, Таблица2 B
          WHERE B.nodeid = A.id AND B.param='key' AND B.value="value"
При этом, желательно иметь индексы по всем этим полям.
21 сен 04, 15:50    [975992]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
SergeyPl
Select A.ID, A.Name FROM Таблица1 A, Таблица2 B
          WHERE B.nodeid = A.id AND B.param='key' AND B.value="value"
При этом, желательно иметь индексы по всем этим полям.


Данный код вытащит запись только для одного параметра.
21 сен 04, 15:54    [976002]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Breakneck
Member

Откуда: Kiev
Сообщений: 2454
SergeyPl
Select A.ID, A.Name FROM Таблица1 A, Таблица2 B
          WHERE B.nodeid = A.id AND B.param='key' AND B.value="value"
При этом, желательно иметь индексы по всем этим полям.


И в where делать перечисление всех параметров? 16 штук, однако...
21 сен 04, 15:54    [976006]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
SergeyPl
Member

Откуда: Харьков
Сообщений: 287

Нужно выбрать из Таблицы1 элементы, для которых существуют записи в Таблица2

Select A.* FROM Таблица1 A, Таблица2 B
          WHERE B.nodeid = A.id
21 сен 04, 15:58    [976025]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
SergeyPl

Нужно выбрать из Таблицы1 элементы, для которых существуют записи в Таблица2

Select A.* FROM Таблица1 A, Таблица2 B
          WHERE B.nodeid = A.id


Не совсем корректно выразился, нужно выбрать из Таблицы1 элементы для которых существуют _определенные_ записи в Таблице2.
При этом в таблице параметров могу быть значения с однинаковыми названиями, т.е.
param ="key"
value ="val1"

param ="key"
value ="val2"

и найти нужно все.
21 сен 04, 16:01    [976036]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
up
21 сен 04, 17:08    [976279]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Breakneck
Member

Откуда: Kiev
Сообщений: 2454
s_zoid
Не совсем корректно выразился, нужно выбрать из Таблицы1 элементы для которых существуют _определенные_ записи в Таблице2.
При этом в таблице параметров могу быть значения с однинаковыми названиями, т.е.
param ="key"
value ="val1"
param ="key"
value ="val2"
и найти нужно все.


Так а чем мой вариант Вам не подходит?
21 сен 04, 17:09    [976284]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
Breakneck
s_zoid
Не совсем корректно выразился, нужно выбрать из Таблицы1 элементы для которых существуют _определенные_ записи в Таблице2.
При этом в таблице параметров могу быть значения с однинаковыми названиями, т.е.
param ="key"
value ="val1"
param ="key"
value ="val2"
и найти нужно все.


Так а чем мой вариант Вам не подходит?


В Вашем варианте получается логика "ИЛИ", то есть выбираем те значения у которых есть хотя бы один из необходимых параметров, а требуется логика "И".
22 сен 04, 07:00    [977152]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
s_zoid
Делал через несколько Exists, но это слишком медленно.
Вообще то EXISTS достаточно шустрая штучка... Индексы какие-нибудь в этих табличках есть? Услугами ITW не пробовал воспользоваться?
22 сен 04, 07:22    [977167]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
tpg
s_zoid
Делал через несколько Exists, но это слишком медленно.
Вообще то EXISTS достаточно шустрая штучка... Индексы какие-нибудь в этих табличках есть? Услугами ITW не пробовал воспользоваться?


в данном случае это получается ОЧЕНЬ медленно.
Индексы на param/(id,param) не поставишь, т.к. он не уникален.

Еще раз формализую задачу:

DECLARE @Base TABLE
(
id int,
param varchar (127),
value varchar (127)
)

INSERT INTO @Base
select 1, 'TradeMark', 'TOYOTA'
INSERT INTO @Base
select 1, 'Model', '2000'
INSERT INTO @Base
select 2, 'TradeMark', 'TOYOTA'
INSERT INTO @Base
select 2, 'Model', 'Civic'


DECLARE @t TABLE
(
param varchar (127),
value varchar (127)
)


INSERT INTO @t
select 'TradeMark', 'TOYOTA'
INSERT INTO @t
select 'Model', '2000'

select * from @Base A
INNER JOIN @t t ON 
A.Param = t.param
AND A.value = t.value
order by a.id

в результате, три строки, последняя не удовлетворяет условию запроса.
22 сен 04, 07:37    [977176]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2386
Блог
create table device(
id int not null primary key,
name varchar(127) not null
)

create table device_property(
device_id int not null foreign key references device,
param varchar(127) not null,
value varchar(127) not null,
constraint device_property_pk primary key nonclustered (device_id, param)
)

-- строгое соответствие всем условиям поиска (AND)

create table search_param(
param varchar(127) not null primary key,
value varchar(127) not null
)

select * from device d
where not exists (select 1 from search_param sp
		where not exists (select 1 from device_property dp
				where dp.device_id = d.id and
					dp.param = sp.param and
					dp.value like sp.value))

-- нестрогое соответствие всем условиям поиска (OR)
drop table search_param

create table search_param(
param varchar(127) not null,
value varchar(127) not null,
constraint serch_param_pk primary key nonclustered (param, value)
)

select * from device d
where exists (select 1 from search_param sp inner join device_property dp
	on dp.device_id = d.id and
		dp.param = sp.param and
		dp.value like sp.value)

drop table search_param
drop table device_property
drop table device
22 сен 04, 08:18    [977202]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Алексей2003.
Guest
Индексы на param/(id,param) не поставишь, т.к. он не уникален.
а вот здесь пожалуйста поподробнее...
22 сен 04, 08:27    [977209]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Алексей2003.
Guest
2s_zoid
P.S. формулируя последний раз свою задачу, вы сами же и ответили на вопрос как... если скорость вас не удовлетворяет, делайте индекс по двум полям.
22 сен 04, 08:29    [977211]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
s_zoid
Member

Откуда: Оттуда
Сообщений: 30
Павел Воронцов
create table device(
id int not null primary key,
name varchar(127) not null
)

create table device_property(
device_id int not null foreign key references device,
param varchar(127) not null,
value varchar(127) not null,
constraint device_property_pk primary key nonclustered (device_id, param)
)

...


Павел Воронцов, спасибо. Единственный рабочий пример в этом топике.
22 сен 04, 09:51    [977354]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить