Une façon est d'utiliser une table temporaire, et le remplir dans une boucle 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
Une autre façon est de créer une liste de positions de caractères valides dans une table temporaire, ou comme dans cet exemple, avec une expression de table commune récursive (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)
Je l'ai testé les échantillons de code contre ce jeu de données:
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 Vous pouvez omettre NAMES de la sous-requête CROSS APPLY – Andomar
J'utilise SQL 2005, ce qui est parfait. Merci! – theaxe