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

Откуда: Саратов
Сообщений: 1203
Всем привет!

Помогите пожалуйста на писать SELECT запрос по следующим условиям

declare @TmpWord table(id int identity(1,1),WordID int, Word varchar(20))

insert into @TmpWord(WordID,Word)
values(1,'привет'),(1,'ривет'),(1,'ивет'),(1,'вет'),(1,'ет'),(1,'т')

insert into @TmpWord(WordID,Word)
values(2,'мир'),(2,'ир'),(2,'р')

-- нужно вывести только те слова где есть оба условия 'и' и 'е'
-- т.е должно получиться слово 'привет' (WordID = 1)
select * from @TmpWord
where Word like('и%') or Word like('е%')


пробовал вариант с рекурсивный CTE, работает но медленно. Есть другие варианты?
27 апр 16, 17:47    [19114098]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Mandarin,

автор
нужно вывести только те слова где есть оба условия 'и' и 'е'

привет ривет ивет тоже есть оба условия, чем они не угодили?
27 апр 16, 17:50    [19114113]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
наверное вы не поняли мой вопрос, я спросил как получить выборку которая соответствует двум (или более) условиям поиска.
27 апр 16, 17:55    [19114132]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Mandarin,

а с какой целью добавлено
автор
(1,'ривет'),(1,'ивет'),(1,'вет'),(1,'ет'),(1,'т')


вообще по вашему запросу where Word like('%и%') AND Word like('%е%') или если нужен порядок
where Word like('%и%е%')
27 апр 16, 17:58    [19114147]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mandarin
наверное вы не поняли мой вопрос, я спросил как получить выборку которая соответствует двум (или более) условиям поиска.

Ну так вы уже написали ее
У вас два критерия, объеденных через логическое ИЛИ
27 апр 16, 18:02    [19114168]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
TaPaK,

изначально задача заключается в следующем:
1. есть таблица со строками (справочник товаров)
2. нужно сделать быстрый поиск по вхождению. как вариант like(%фильтр%). но like(%фильтр%) не использует индекс и поиск работает не так быстро как хотелось бы.

поэтому я ищу варианты как ускорить поиск
27 апр 16, 18:04    [19114177]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Mandarin,

аж поперхнулся... вы аккуратнее с оптимизацией... показывайте запросы, индексы план и не занимайтесь извращением.
27 апр 16, 18:06    [19114184]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
Glory
Mandarin
наверное вы не поняли мой вопрос, я спросил как получить выборку которая соответствует двум (или более) условиям поиска.

Ну так вы уже написали ее
У вас два критерия, объеденных через логическое ИЛИ


мой запрос написан с ошибкой, я его написал просто для примера.

мне нужна выборка, в которой слова соответствуют всем условиям поиска а в моем запросе выборка вернет значения если хотя бы одно условие выполняется.
27 апр 16, 18:06    [19114186]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
TaPaK,
если вам нечего сказать по существу, лучше промолчать.
27 апр 16, 18:07    [19114196]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mandarin
нужно сделать быстрый поиск по вхождению

"по вхождению" - это
по началу слов в строке
вообще где угодно в строке
27 апр 16, 18:07    [19114198]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
Mandarin
Есть другие варианты?

На первый взгляд, задача решается легко:
declare @TmpWord table(id int identity(1,1),WordID int, Word nvarchar(20))

insert into @TmpWord(WordID,Word)
values(1,N'привет'),(1,N'ривет'),(1,N'ивет'),(1,N'вет'),(1,N'ет'),(1,N'т')

insert into @TmpWord(WordID,Word)
values(2,N'мир'),(2,N'ир'),(2,N'р')

select WordID
from (
	select WordID, count(*) as cnt from @TmpWord
	where Word like(N'и%') or Word like(N'е%')
	group by WordID
	having count(*) = 2
) t

Но будет считать неправильно, если несколько раз встречается одно условие, например
insert into @TmpWord(WordID,Word)
values(3,N'мимимие'),(3,N'имимие'),(3,N'мимие'),(3,N'имие'),(3,N'мие'),(3,N'ие'),(3,N'е')

Поэтому пишем по другому:
declare @TmpWord table(id int identity(1,1),WordID int, Word nvarchar(20))

insert into @TmpWord(WordID,Word)
values(1,N'привет'),(1,N'ривет'),(1,N'ивет'),(1,N'вет'),(1,N'ет'),(1,N'т')

insert into @TmpWord(WordID,Word)
values(2,N'мир'),(2,N'ир'),(2,N'р')

insert into @TmpWord(WordID,Word)
values(3,N'мимимие'),(3,N'имимие'),(3,N'мимие'),(3,N'имие'),(3,N'мие'),(3,N'ие'),(3,N'е')

-- неправильно
select WordID
from (
	select WordID, count(*) as cnt from @TmpWord
	where Word like(N'и%') or Word like(N'е%')
	group by WordID
	having count(*) = 2
) t

-- правильно
select WordID
from (
	select WordID, count(*) as cnt 
	from (
		select 1 as part, WordID from @TmpWord where Word like(N'и%') 
		union
		select 2 as part, WordID from @TmpWord where Word like(N'е%') 
	) t
	group by WordID
	having count(*) = 2
) t
27 апр 16, 18:09    [19114205]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mandarin
мне нужна выборка, в которой слова соответствуют всем условиям поиска а в моем запросе выборка вернет значения если хотя бы одно условие выполняется.

а вы только OR знаете ? а AND не знаете ?
27 апр 16, 18:10    [19114207]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
Glory,

вот жеж попал в вагон для некурящих :)
27 апр 16, 18:10    [19114209]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mandarin
вот жеж попал в вагон для некурящих :)

Во-во, вы точно что-то курили
27 апр 16, 18:11    [19114213]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
alexeyvg
Mandarin
Есть другие варианты?

На первый взгляд, задача решается легко:
declare @TmpWord table(id int identity(1,1),WordID int, Word nvarchar(20))

insert into @TmpWord(WordID,Word)
values(1,N'привет'),(1,N'ривет'),(1,N'ивет'),(1,N'вет'),(1,N'ет'),(1,N'т')

insert into @TmpWord(WordID,Word)
values(2,N'мир'),(2,N'ир'),(2,N'р')

select WordID
from (
	select WordID, count(*) as cnt from @TmpWord
	where Word like(N'и%') or Word like(N'е%')
	group by WordID
	having count(*) = 2
) t

Но будет считать неправильно, если несколько раз встречается одно условие, например
insert into @TmpWord(WordID,Word)
values(3,N'мимимие'),(3,N'имимие'),(3,N'мимие'),(3,N'имие'),(3,N'мие'),(3,N'ие'),(3,N'е')

Поэтому пишем по другому:
declare @TmpWord table(id int identity(1,1),WordID int, Word nvarchar(20))

insert into @TmpWord(WordID,Word)
values(1,N'привет'),(1,N'ривет'),(1,N'ивет'),(1,N'вет'),(1,N'ет'),(1,N'т')

insert into @TmpWord(WordID,Word)
values(2,N'мир'),(2,N'ир'),(2,N'р')

insert into @TmpWord(WordID,Word)
values(3,N'мимимие'),(3,N'имимие'),(3,N'мимие'),(3,N'имие'),(3,N'мие'),(3,N'ие'),(3,N'е')

-- неправильно
select WordID
from (
	select WordID, count(*) as cnt from @TmpWord
	where Word like(N'и%') or Word like(N'е%')
	group by WordID
	having count(*) = 2
) t

-- правильно
select WordID
from (
	select WordID, count(*) as cnt 
	from (
		select 1 as part, WordID from @TmpWord where Word like(N'и%') 
		union
		select 2 as part, WordID from @TmpWord where Word like(N'е%') 
	) t
	group by WordID
	having count(*) = 2
) t


большое спасибо! отличный вариант!
27 апр 16, 18:12    [19114216]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
Glory
Mandarin
вот жеж попал в вагон для некурящих :)

Во-во, вы точно что-то курили
Это же известный алгоритм полнотекстовой индексации от DeColo®es :-)
Не помню только, какой он делал запрос, но видимо что то вроде этого...
27 апр 16, 18:16    [19114233]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
alexeyvg
Glory
пропущено...

Во-во, вы точно что-то курили
Это же известный алгоритм полнотекстовой индексации от DeColo®es :-)
Не помню только, какой он делал запрос, но видимо что то вроде этого...

т.е. только извращения? а как же например http://aboutsqlserver.com/2015/01/20/optimizing-substring-search-performance-in-sql-server/
27 апр 16, 18:18    [19114240]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
TaPaK
alexeyvg
пропущено...
Это же известный алгоритм полнотекстовой индексации от DeColo®es :-)
Не помню только, какой он делал запрос, но видимо что то вроде этого...

т.е. только извращения? а как же например http://aboutsqlserver.com/2015/01/20/optimizing-substring-search-performance-in-sql-server/
Эээ, думаете, сканирование быстрее. чем поиск по индексу??? Это же просто небольшая оптимизация скана, за счёт бинари-поиска. Вы вообще отказались от индексов в БД, после прочтения этой статьи? :-)
Не говоря, что он не всегда приемлим (не зря же придумали правила сортировки, коллейты?), он ещё и безобразно медленный.
А тут получается эффективный индексированный поиск
27 апр 16, 18:27    [19114268]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
Mandarin
Member

Откуда: Саратов
Сообщений: 1203
alexeyvg
TaPaK
пропущено...

т.е. только извращения? а как же например http://aboutsqlserver.com/2015/01/20/optimizing-substring-search-performance-in-sql-server/
Эээ, думаете, сканирование быстрее. чем поиск по индексу??? Это же просто небольшая оптимизация скана, за счёт бинари-поиска. Вы вообще отказались от индексов в БД, после прочтения этой статьи? :-)
Не говоря, что он не всегда приемлим (не зря же придумали правила сортировки, коллейты?), он ещё и безобразно медленный.
А тут получается эффективный индексированный поиск


я сейчас попробовал ваш вариант на рабочем сервере, результат самый лучший из того что я пробовал, спасибо вам еще раз!
27 апр 16, 18:43    [19114336]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
alexeyvg
TaPaK
пропущено...

т.е. только извращения? а как же например http://aboutsqlserver.com/2015/01/20/optimizing-substring-search-performance-in-sql-server/
Эээ, думаете, сканирование быстрее. чем поиск по индексу??? Это же просто небольшая оптимизация скана, за счёт бинари-поиска. Вы вообще отказались от индексов в БД, после прочтения этой статьи? :-)
Не говоря, что он не всегда приемлим (не зря же придумали правила сортировки, коллейты?), он ещё и безобразно медленный.
А тут получается эффективный индексированный поиск
никто не оспаривает эффективность, но надо ж еще справочник сумасшедший иметь для реализации и минимум всегда актуальный
27 апр 16, 20:59    [19114655]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
TaPaK
alexeyvg
пропущено...
Эээ, думаете, сканирование быстрее. чем поиск по индексу??? Это же просто небольшая оптимизация скана, за счёт бинари-поиска. Вы вообще отказались от индексов в БД, после прочтения этой статьи? :-)
Не говоря, что он не всегда приемлим (не зря же придумали правила сортировки, коллейты?), он ещё и безобразно медленный.
А тут получается эффективный индексированный поиск
никто не оспаривает эффективность, но надо ж еще справочник сумасшедший иметь для реализации и минимум всегда актуальный
Справочник получается маленький, слов то немного в известных языках.
Ну, 50 тыщ слов, ещё 50 тыщ названий и имён, ну умножаем на среднюю длину. Ну миллион записей в таблице. Это же копейки.
Ещё будут "уникальные" слова, которые не-слова. Например, цифры, гуиды и т.д., таких на документ единицы процентов, в самом худшем случае, а в большинстве документов вообще таких практически нету.

И вообще, концептуально это соответствует размерам обычного полнотекстового индекса, умноженным на среднее количество букв в слове.
Т.е. немало, но вполне обыденно, не нечто запредельное.

Это мы говорили про словарь, то есть он страшный с виду, но на самом деле маленький (вопрос в посте как раз про поиск в нём).

Вот сам индекс, то есть вхождение слов в документы, он действительно большой (зависит от базы документов).
Но этот индекс ровно такой же, как индекс в любой системе полнотекстовой индексации, в том числе встроенной в сиквел, тут ничего нового не придумать.
28 апр 16, 00:25    [19115234]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
alexeyvg
Glory
пропущено...

Во-во, вы точно что-то курили
Это же известный алгоритм полнотекстовой индексации от DeColo®es :-)
Не помню только, какой он делал запрос, но видимо что то вроде этого...
Генераторы в MSSQL
28 апр 16, 10:19    [19115974]     Ответить | Цитировать Сообщить модератору
 Re: помогите пожалуйста написать SELECT запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
iap
alexeyvg
пропущено...
Это же известный алгоритм полнотекстовой индексации от DeColo®es :-)
Не помню только, какой он делал запрос, но видимо что то вроде этого...
Генераторы в MSSQL
Не ту ссылку кинул!
Что делать, когда Full-Text бессилен
28 апр 16, 10:22    [19115995]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить