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

Откуда:
Сообщений: 25
Имеется таблица, состоящая из двух колонок
ID и ФИО

ID; Фамилия Имя Отчество
1; Иванов Игорь
2; Андрей Александрович
3; Дмитрий Петров
4; Жан Мария Николай ибн Бруни ибн Хаттаб
...


при этом любая часть может быть пропущена и находиться на на любом месте по отношению друг к другу.

пользователь вводит строку поиска при этом неизвестно на каком месте он поставит Ф И О и заполнит ли вообще часть полей

как сделать выборку по введёному критерию поиска?
23 дек 04, 01:31    [1202460]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
vma_mnt
Member

Откуда: Новокузнецк
Сообщений: 602
select * from Table where ФИО like '%ЧтоВвелПользователь%'
23 дек 04, 05:18    [1202542]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
Тогда уж так:
select *
from Table
where
        ([ФИО] like '%Фамилия%')
  and ([ФИО] like '%Имя%')
  and ([ФИО] like '%Отчество%')
23 дек 04, 06:20    [1202553]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
zzzxxx
Member

Откуда:
Сообщений: 25
Trong
Тогда уж так:
select *
from Table
where
        ([ФИО] like '%Фамилия%')
  and ([ФИО] like '%Имя%')
  and ([ФИО] like '%Отчество%')


Не проходит так как пользователь может набрать больше ТРЁХ слов например:
"Жан Мария ибн Бруни"

Я понимаю что строку поиска надо преобразовать в таблицу (и могу это сделать), а вот как дальше поступать - не понятно.
23 дек 04, 08:23    [1202660]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
sti
Member

Откуда:
Сообщений: 769
вводимую пользователем строку надо разбить на слова и дальше как Trong сказал
23 дек 04, 08:33    [1202673]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
VladRUS.ca
Member

Откуда: Toronto
Сообщений: 1172
Посмотрите BOL: Full-text Search - неплохая штука
23 дек 04, 08:35    [1202680]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
VladRUS.ca
Member

Откуда: Toronto
Сообщений: 1172
Выражения типа like '%Фамилия%' никак не используют индексы.
Если у Вас таблица большая то будет очень медленно работать

Как один из вариантов можно создать дополнительную таблицу ФИО_Split типа:
ID Names
1 Иванов
1 Игорь
2 Андрей
2 Александрович
3 Дмитрий
3 Петров
4 Жан
4 Мария
4 Николай
4 ибн
4 Бруни
4 ибн
4 Хаттаб

... выборка по введёному критерию поиска...
select *
from ФИО
where ID in (
    select distinct ID 
    from ФИО_Split
    where Names in(@key1, @key2, ...@keyN)) -- некоторые поля поиска в клиентской части  могут быть пустыми 
23 дек 04, 09:30    [1202792]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
zzzxxx
Не проходит так как пользователь может набрать больше ТРЁХ слов например:
"Жан Мария ибн Бруни"

Я понимаю что строку поиска надо преобразовать в таблицу (и могу это сделать), а вот как дальше поступать - не понятно.

Например так

declare @t table (word nvarchar(50))
--как то заполняем её искомыми словами
select *
from Table t1 join
     @t t2 on t1.[Фамилия Имя Отчество] like '%' + t2.word + '%'
23 дек 04, 09:32    [1202799]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Упустил - в моем запросе distinct не помешает.
23 дек 04, 09:34    [1202805]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
Beaver
Member

Откуда:
Сообщений: 210
select *
from Table
where
[ФИО] like replace(ТоЧтоВвелПользователь,' ','%')
23 дек 04, 09:52    [1202868]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
Beaver
Member

Откуда:
Сообщений: 210
более правильно
select *
from Table
where
[ФИО] like '%'+replace(ТоЧтоВвелПользователь,' ','%')+'%'
23 дек 04, 09:56    [1202882]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
tpg
zzzxxx
Не проходит так как пользователь может набрать больше ТРЁХ слов например:
"Жан Мария ибн Бруни"

Я понимаю что строку поиска надо преобразовать в таблицу (и могу это сделать), а вот как дальше поступать - не понятно.

Например так

declare @t table (word nvarchar(50))
--как то заполняем её искомыми словами
select *
from Table t1 join
     @t t2 on t1.[Фамилия Имя Отчество] like '%' + t2.word + '%'

Я так понимаю, что указанный запрос вернет все записи в которых есть любая составляющая "Жан Мария ибн Бруни" ... т.е., например, всех у кого имя Мария. Я не прав?
23 дек 04, 09:57    [1202896]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
Beaver
select *
from Table
where
[ФИО] like replace(ТоЧтоВвелПользователь,' ','%')

Не канает - пользователь мог ввести "Мария Жан ибн Бруни" вместо "Жан Мария ибн Бруни" и тогда ничего не выйдет.
23 дек 04, 09:59    [1202910]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Trong
Я так понимаю, что указанный запрос вернет все записи в которых есть любая составляющая "Жан Мария ибн Бруни" ... т.е., например, всех у кого имя Мария. Я не прав?
Йез
23 дек 04, 10:09    [1202936]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
Что-то типа этого ... Но ме-е-е-едленно
declare @t table (word nvarchar(50))
--как то заполняем её искомыми словами

declare @sql varchar(8000)
set @sql = 'select * from Table where '

select @sql = @sql + '([ФИО] like ''%' + word + '%'') and'
from @t

set @sql = left(@sql, len(@sql)-4)
exec(@sql)

Либо строить сплит-таблицу.
23 дек 04, 11:36    [1203387]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
А оно здесь по-любому будет ме-е-е-едленно
23 дек 04, 11:47    [1203446]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2423
tpg
А оно здесь по-любому будет ме-е-е-едленно

Поэкспериментировал, делюсь впечатлениями...
if object_id('fn_check_fio') is not null drop function fn_check_fio
go
create function fn_check_fio(@likestr varchar(8000),@fio varchar(8000))
returns float
--returns varchar(8000)
as begin
 declare @res bit, @words int, @matchs int, @s int, @e int, @debug varchar(8000)
 select @res=0,@s=0, @e=0, @matchs=0, @words=0, @debug=''
 --чтобы не "мучиться" с последним словом
 set @likestr=ltrim(rtrim(@likestr))+' '
 if len(@likestr)=1 return 0.0
 set @e=charindex(' ',@likestr)
 while @e>0 begin
   if len(ltrim(substring(@likestr,@s+1,@e-@s-1)))>0 begin
	set @words=@words+1
	--set @debug=@debug+substring(@likestr,@s+1,@e-@s-1)+','
	if @fio like '%'+substring(@likestr,@s+1,@e-@s-1)+'%' set @matchs=@matchs+1
   end
   set @s=@e
   set @e=charindex(' ',@likestr,@s+1)
 end
 return @matchs*1.0/@words
 --return @debug
end
go
--select dbo.fn_check_fio('  Мария Жан ибн  Хаттаб ибн Бруни','Жан Мария Николай ибн Бруни ибн Хаттаб')
declare @t table(id int,fio varchar(8000))
insert @t select top 100000 a.id,a.name
	+space(1+cast(rand(a.id)*2 as int))+left(b.name,10)
	+space(1+cast(rand(b.id)*2 as int))+right(c.name,10)
	+space(1+cast(rand(c.id)*2 as int))+d.name
from sysobjects a, sysobjects b, sysobjects c, sysobjects d

declare @start datetime
set @start=getdate()
select * from @t where dbo.fn_check_fio('systypes sysobjects',fio)=1.0
--результаты: 29376, 29640, 29783
print 'udf time='+convert(varchar,datediff(ms,@start,getdate()))
set @start=getdate()
select * from @t where fio like '%systypes%sysobjects%' or fio like '%sysobjects%systypes%'
--результаты: 9110, 9126, 9106
print 'like time='+convert(varchar,datediff(ms,@start,getdate()))
В три раза медленней! Зато с udf - сам себе барин :)
select * from @t where dbo.fn_check_fio('systypes sysobjects',fio)>=0.5
23 дек 04, 14:15    [1204371]     Ответить | Цитировать Сообщить модератору
 Re: Поиск Фамилия Имя Отчество  [new]
zzzxxx
Member

Откуда:
Сообщений: 25
Спасибо всем вопрос закрыт.
Юрий
24 дек 04, 10:17    [1206710]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить