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

Посоветуйте с запросом, плз

есть такие 2-е таблички
Товары - items (gr varchar(10), name varchar(10), price money, flag bit)
gr name price flag
group1 item5 15.4000 0
group2 item6 177.0000 0
group1 item545 1.0000 0
group5 item23 1234.0000 0
group1 item18 20.0000 0
group1 item8 1001.0000 0

Фильтр товаров - filters (f_gr varchar(10), f_name varchar(10), f_price varchar(10))
f_gr f_name f_price
item5%
<10
20
group1 >1000

f_gr - фильтр по gr (может быть с подстановочными символами - % или _)
f_name - фильтр по name (может быть с подстановочными символами - % или _)
f_price - фильтр по price (может быть с знаками сравнения > , < , <= , >=)

мне нужно "пометить" (установить flag=1) в таб.items тем товарам, которые удовлетворяют шаблонам

т.е. в результате должно быть так
gr name price flag
group1 item5 15.4000 1
group2 item6 177.0000 0
group1 item545 1.0000 1
group5 item23 1234.0000 0
group1 item18 20.0000 1
group1 item8 1001.0000 1


я представляю, как это можно сделать циклом по таб.filters и динамическим запросом, но может есть вариант по-лучше ... ?

вопрос :
можно ли (и стоит ли) сделать всё в один запрос ? как ?

выполнятся "пометка" будет в ХП, так что допустимо использование каких-нибудь времянок для преобразования (если нужно)

сервер - MS SQL 2000

спасибо!
+ скрипты

declare @items table(gr varchar(10), name varchar(10), price money, flag bit)

insert into @items

select 'group1', 'item5', 15.40, 0 union all
select 'group2', 'item6', 177, 0 union all
select 'group1', 'item545', 1, 0 union all
select 'group5', 'item23', 1234, 0 union all
select 'group1', 'item18', 20, 0 union all
select 'group1', 'item8', 1001, 0

declare @filters table(f_gr varchar(10), f_name varchar(10), f_price varchar(10))

insert into @filters

select null, 'item5%', null union all
select null, null, '<10' union all
select null, null, '20' union all
select 'group1', null, '>1000'

--select * from @items

--select * from @filters
30 авг 12, 12:55    [13088099]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
ъ, ну, в качестве извращения для тренировки, есть вариант.

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

update i 
set flag = 1
  from @items i
  inner join @filters f
          on (i.gr like f.f_gr or f_gr is null)
         and (i.name like f.f_name or f.f_name is null)
         and (case when f.f_price is null then 1
                   when substring(f.f_price, 1, 1) = '<' and  i.price < CAST(substring(f.f_price, 2, len(f_price) - 1) AS int) then 1
                   when substring(f.f_price, 1, 1) = '>' and  i.price > CAST(substring(f.f_price, 2, len(f_price) - 1) AS int) then 1
                   when substring(f.f_price, 1, 1) not in ('>', '<') and i.price = CAST(f.f_price as int) then 1
                   else 0
                  end = 1)

select * from @items
30 авг 12, 13:16    [13088307]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
ъ
можно ли (и стоит ли) сделать всё в один запрос ? как ?
Сделать то можно, только может быть медленно...

select distinct i.name
from @items i
	join @filters f on
		i.gr like isnull(f.f_gr, '%')
		and
		i.name like isnull(f.f_name, '%')
		and 
		(
			f.f_price is null
			or (f.f_price like '=%' and i.price = substring(f.f_price, 2, 1000))
			or (f.f_price like '>%' and i.price > substring(f.f_price, 2, 1000))
			or (f.f_price like '>=%' and i.price >= substring(f.f_price, 3, 1000))
			or (f.f_price like '<%' and i.price < substring(f.f_price, 2, 1000))
			or (f.f_price like '<=%' and i.price <= substring(f.f_price, 3, 1000))
		)
30 авг 12, 13:20    [13088336]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
Minamoto
Не рекомендовал бы его использовать в реальной среде, поскольку может быть очень много "Но" - например, достаточно добавить один оператор в последнюю колонку, и код упадет - нужно будет переписывать.
Можно проверять чек-констрейном.

Вопрос здесь скорее к производительности...
30 авг 12, 13:21    [13088356]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
ъ,

На мой взгляд, в таком варианте таблицы фильтров, чтобы не было просадок по скорости, наиболее приемлемым вариантом, будет собирать запрос динамически.
Вот вам еще в помощь статейка Dynamic Search Conditions in T-SQL. Вдруг пригодится.
30 авг 12, 13:24    [13088391]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Если привести таблицу фильтров к виду
f_grf_namef_price_lowboundf_price_highbound
%item5%1922337203685477.5807
%%19
%%2020
group1%1001922337203685477.5807
То нужный запрос станет элементарным.
30 авг 12, 13:47    [13088610]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
invm
Если привести таблицу фильтров к виду
...
То нужный запрос станет элементарным.
Вообще да, самый правильный вариант.
30 авг 12, 14:33    [13088906]     Ответить | Цитировать Сообщить модератору
 Re: Фильтрация таблицы по шаблонам из другой таблицы  [new]
ъ
Guest
alexeyvg
invm
Если привести таблицу фильтров к виду
...
То нужный запрос станет элементарным.
Вообще да, самый правильный вариант.

угу )), вот сижу-смотрю и не понимаю, почему я до этого не додумался сразу ... :)

правда уже написал, вариант с case-ом, по примеру Minamoto
значит ещё попробую с времянкой
будет 3-и ХП, заодно - сравню по скорости

всем большое спасибо !
30 авг 12, 14:46    [13089006]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить