Разделите фразу на слова с одинарными кавычками и запятой в SQL Server, используя TSQL - PullRequest
0 голосов
/ 28 октября 2019

У меня есть поисковый запрос, в котором я использую оператор Like для поиска по ключевому слову, теперь мне нужно предоставить пользователю возможность поиска как exact phase или поиск all words по поисковым ключевым словам

Поиск по ключевому слову = mission to mars

Поисковый запрос

 Select * from Table` WHERE  Title LIKE '%mission to mars%' OR Details LIKE '%mission to mars%'

Теперь мне нужно преобразовать этот запрос, чтобы он выполнял поиск всех слов по ключевым словам mission to mars

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

Select * from Table` WHERE  Title IN ('mission', 'to', 'mars') OR Details IN ('mission, 'to', 'mars')

Можно ли с помощью любой функции SQL разбить поисковое ключевое слово mission to mars и преобразовать его в строку с каждым словом, заключенным в одинарные кавычки и разделенным запятой, например 'mission', 'to', 'mars'

STRING_SPLIT могло бы быть решением, но оно работает в SQL SERVER 2016 и выше, пока я использую SQL 2014.

Я могу разделитьключевое слово из C # оно само и передает его как 'mission', 'to', 'mars' в хранимую процедуру, но мне интересно, могу ли я разделить его в самом T-SQL

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Вы можете смоделировать функциональность STRING_SPLIT() с помощью рекурсивного CTE, который вернет все слова фразы:

declare @s varchar(100) = 'mission to mars';
with 
  cte as (
    select 1 n1, charindex(' ', @s) n2
    union all
    select n2 + 1, charindex(' ', @s, n2 + 1)
    from cte
    where n2 > 0
  ),
  words as (
    select substring(
      @s, 
      n1, 
      case when n2 > 0 then n2 - n1 else len(@s) end
    ) word
    from cte
  )
select * from words;

См. Демоверсию . Результаты:

> | word    |
> | :------ |
> | mission |
> | to      |
> | mars    |

Так что вы можете использовать это так:

select * from tablename WHERE Title IN (select * from words)
0 голосов
/ 28 октября 2019

- Создать функцию 'fn_split_string', которая разбивает строку

create function dbo.fn_split_string(@str nvarchar(1000),@sep nvarchar(1))
returns @tab_split  table (id int identity(1,1),str nvarchar(1000) )  
as  

begin  
declare @str1 as nvarchar(1000)  
declare @istr as nvarchar(1000)  
declare @i as integer  
set @str1=@str  
set @i=2  
while @i>0 
begin  
set @i=charindex(@sep,@str1,1)  
if @i>0  
begin  
set @istr=substring(@str1,1,@i-1)  
insert into @tab_split(str) values(@istr)  
set @str1=substring(@str1,@i+1,len(@str1))  
end  
end  
insert into @tab_split(str) values(@str1)  
return   
end

- Вы можете запустить функцию следующим образом

select * from dbo.fn_split_string ('mission to mars',' ')

- Следующий скрипт

Select * from Table` WHERE  Title IN ('mission', 'to', 'mars') OR Details IN ('mission, 'to', 'mars')

- становится

select * from Table t1 inner join dbo.fn_split_string ('mission to mars',' ') t2
on t1.title=t2.str or t1.details=t2.str

- надеюсь, это поможет

- **

Другое решение, которое позволяет избежать использования циклов, так как"Zohar Peled" посоветовал

**

создать таблицу tab_numbers (Number int);

with cte as (select 1 n union all select 1+n from cte where n+1 <=100)
insert into tab_numbers select * from cte
option(maxrecursion 0)

go




create FUNCTION fn_split_string_2
(
   @str       NVARCHAR(MAX),
   @sep  NVARCHAR(255)
)
RETURNS @tab_split table (str  nvarchar(max))

AS
  begin
  if @sep=' ' 
  begin
    set @sep=',' 
    set @str=replace(@str,' ',',')
  end


   insert into @tab_split

       SELECT Item = SUBSTRING(@str, Number, 
         CHARINDEX(@sep, @str + @sep, Number) - Number)
       FROM tab_numbers
       WHERE Number <= CONVERT(INT, LEN(@str))
         AND SUBSTRING(@sep + @str, Number, LEN(@sep)) = @sep
   ;
   return
   end
GO
...