Один из способов заключается в использовании временной таблицы, и заполнить его в цикле WHILE:
declare @letters table (letter varchar(1))
declare @pos int
set @pos = 1
while 1=1
begin
insert into @letters
select substring(name,@pos,1)
from @names
where len(name) >= @pos
if @@rowcount = 0
break
set @pos = @pos + 1
end
select letter, count(*)
from @letters
group by letter
Другой способ заключается в создании списка допустимых позиций символов во временной таблице, или, как в данном примере, с рекурсивным общего табличного выражения (CTE):
declare @maxLen int
select @maxLen = max(len(name)) from @names
;WITH CharPositions (i) AS (
select 1
union all
select i+1
from CharPositions
where i < @maxLen
)
select substring(n.name,cp.i,1), count(*)
from @names n
inner join CharPositions cp on cp.i <= len(n.name)
group by substring(n.name,cp.i,1)
Я протестировали образцы кода против этого набора данных:
declare @names table (name varchar(max))
insert into @names values ('abc')
insert into @names values ('def')
insert into @names values ('def')
insert into @names values ('g')
insert into @names values ('g')
insert into @names values ('g')
+1 Вы можете опустить NAMES из подзапроса CROSS APPLY – Andomar
Я использую SQL 2005, так что это прекрасно. Благодаря! – theaxe