#sql-server
Вопрос:
Мне нужно количество всех символов, которые появляются в word. Например, если я напишу Питер, я хочу, чтобы результат был таким
P 1
e 2
t 1
e 2
r 1
Любая помощь будет признательна.
Комментарии:
1. Почему вы хотите сделать это в SQL Server ? Это не имеет никакого отношения к SQL Server
Ответ №1:
Если открыт для ТВФ. Будучи функцией с табличным значением, она может использоваться в CROSS APPLY
Пример
Select *
,Cnt = sum(1) over (partition by RetVal)
From [dbo].[tvf-Str-Parse-Char]('Peter')
Order By RetSeq
ВОЗВРАТ
RetSeq RetVal Cnt
1 P 1
2 e 2
3 t 1
4 e 2
5 r 1
Функция, если это интересно
CREATE FUNCTION [dbo].[tvf-Str-Parse-Char] (@String varchar(max))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From cte1 a,cte1 b,cte1 c,cte1 d,cte1 e,cte1 f)
Select RetSeq=N
,RetVal=Substring(@String,N,1)
From cte2
)
--Max 1 Million Observations
--Select * from [dbo].[tvf-Str-Parse-Char]('this is a string')
Комментарии:
1. Почему
DATALENGTH
и почему нетLEN
?2. @Charlieface Конечные пробелы в строке. Лен будет игнорировать, в то время как длина данных будет их считать
3. @Charlieface извините .. только 1 кофе этим утром. dbfiddle.uk/…
Ответ №2:
То, что Джон опубликовал выше, известно как функция Unigram; ОНА же N-Грамм размера 1. Для функции N-граммов, которая поддерживает токены любого размера, см.: Nasty Fast N-Граммы, часть 1. Существует версия 8K и VARCHAR(MAX). Использование ngrams8k:
DECLARE @string VARCHAR(100) = 'Peter';
SELECT ng.Position, ng.Token, COUNT(ng.Token) OVER (PARTITION BY ng.Token) AS cnt
FROM dbo.ngrams8k(@string,1) AS ng
ORDER BY ng.Position;
ВОЗВРАТ:
Position Token cnt
----------- ---------- -----------
1 P 1
2 e 2
3 t 1
4 e 2
5 r 1
Обратите внимание, что вторым параметром в функции является размер токена, вот основной пример того, что вы можете сделать помимо юниграмм. Допустим, мы хотели найти строку для всех экземпляров определенной подстроки, «ABC» в этом примере:
DECLARE
@string VARCHAR(8000) = '123ABC xxx yyy ABCDEABC...ABB',
@searchFor VARCHAR(100) = 'ABC';
SELECT ng.*
FROM dbo.Ngrams8k(@string,LEN(@searchFor)) AS ng
WHERE ng.Token = @searchFor;
ВОЗВРАТ:
position token
----------- -------
4 ABC
16 ABC
21 ABC