Хорошо, давайте запишем условия поиска во временную таблицу:
CREATE TABLE #SearchTerms (Term varchar(50) not null)
insert into #SearchTerms (Term)
select 'yellow' union all
select 'large' union all
select 'widgets'
И давайте сделаем что-нибудь глупое:
select
widgets.ID,
(LEN(description) - LEN(REPLACE(description,Term,''))) / LEN(Term) as DescScore
(LEN(title) - LEN(REPLACE(title,Term,''))) / LEN(Term) as TitleScore
from
widgets,#SearchTerms
Теперь мы посчитали каждое вхождение каждого термина как в описании, так и в заголовке.
Итак, теперь мы можем суммировать и взвешивать эти случаи:
select
widgets.ID,
SUM((LEN(description) - LEN(REPLACE(description,Term,''))) / LEN(Term) +
((LEN(title) - LEN(REPLACE(title,Term,''))) / LEN(Term) *5)) as CombinedScore
from
widgets,#SearchTerms
group by
Widgets.ID
И если нам нужно сделать больше с этим, я бы рекомендовал поместить вышеупомянутое в подвыбор
select
w.*,CombinedScore
from
widgets.w
inner join
(select
widgets.ID,
SUM((LEN(description) - LEN(REPLACE(description,Term,''))) / LEN(Term) +
((LEN(title) - LEN(REPLACE(title,Term,''))) / LEN(Term) *5)) as CombinedScore
from
widgets,#SearchTerms
group by
Widgets.ID
) t
on
w.ID = t.ID
where
CombinedScore > 0
order by
CombinedScore desc
(обратите внимание, что я предположил, что во всех этих примерах есть столбец идентификатора, но его можно расширить на столько столбцов, сколько необходимо для определения PK в таблице виджетов)
Настоящий трюк здесь заключается в подсчете вхождений слова в большую часть текста, что делается с помощью:
(LEN(text) - LEN(text with each occurrence of term removed)) / LEN(term)