2009-10-21 46 views

回答

2

通用的答案是,你需要在每個名字分成組成字符表,然後數這些。

您沒有提及您正在使用的RDBMS。數據庫引擎的答案有所不同。

例如,這將在SQL 2005+工作:

DECLARE @friends TABLE (NAMES VARCHAR(30)) 
DECLARE @maxLen INT 

INSERT @friends (NAMES) 
SELECT 'Edward' 
UNION SELECT 'James' 
UNION SELECT 'Mike' 

SELECT @maxLen = MAX(LEN(NAMES)) FROM @friends 

;WITH numsCte 
AS 
( 
     --dynamic numbers table. If you have a numbers table in your database 
     --use that instead, as it will be more efficient. 
     SELECT 1 AS n 
     UNION ALL 
     SELECT n+1 FROM numsCte 
     WHERE n < @maxLen 
) 
,charCTE 
AS 
( 
     --split the string into a dataset 
     SELECT * 
     FROM numsCte AS nm 
     CROSS APPLY (SELECT NAMES, SUBSTRING(NAMES, n, 1) AS splitChar 
        FROM @friends 
        ) AS st 
     WHERE splitChar > '' 
) 
SELECT UPPER(splitChar) AS letter 
     ,COUNT(1) AS cnt 
FROM charCTE 
GROUP BY splitChar 
ORDER BY splitChar 

但幾乎可以肯定不會在任何其他數據庫引擎的工作。

+0

+1您可以忽略CROSS APPLY子查詢中的NAMES – Andomar 2009-10-21 11:20:44

+0

我正在使用SQL 2005,因此非常完美。謝謝! – theaxe 2009-10-22 08:57:34

0

一種方法是使用臨時表,並填充它在一個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') 
相關問題