我正在使用SQL Server Management Studio v17.9.1。我在包含字母数字字符串的数据库表中有列。我需要对字符串中的字母进行计数,并生成一个汇总结果表,其中显示了通过对列中具有该字母数的记录的计数来显示字母数。
如果可能的话,我还尝试使列表动态化,以使聚合结果中的行达到表列中字符串的最大字母数。
到目前为止,我发现的示例似乎逐个字符地扫描字符串,这将非常耗费性能,并且我也查看了replace函数,但它看起来不适用于regex,因此我必须替换每个函数依次输入字母。
感谢您的帮助。
例如:Table1
ID
----------
A00001
AB0001
AC123
CB00AD
1234AD
汇总结果:
No of letters Count of records
----------- -----------
1 1
2 3
3 0
4 1
答案 0 :(得分:2)
这是使用临时提示表的另一种选择
示例
Declare @YourTable Table ([ID] varchar(50))
Insert Into @YourTable Values
('A00001')
,('AB0001')
,('AC123')
,('CB00AD')
,('1234AD')
Select Letters
,Cnt = count(*)
From (
Select Letters = count(*)
From @YourTable A
Join (
Select Top (select max(len(ID)) from @YourTable) N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1
) B on n<=len(ID)
Where substring(ID,N,1) not like '[0-9]'
Group By ID
) A
Group By Letters
返回
Letters Cnt
1 1
2 3
4 1
答案 1 :(得分:1)
一种简单的方法是基于替换
SELECT LEN(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(myColumn, '0', ''),
'1',''),
'2',''),
'3',''),
'4',''),
'5',''),
'6',''),
'7',''),
'8',''),
'9','')
) num_char
from your_table
答案 2 :(得分:1)
您可以受益于内联表值函数的性能来执行计数。如果您了解该函数的代码,则可以根据需要使用计数表生成空行。
CREATE FUNCTION dbo.CountChars(
@String varchar(8000),
@Pattern varchar(100)
)
RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
WITH
E(n) AS(
SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
SELECT a.n FROM E a, E b
),
E4(n) AS(
SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
SELECT TOP( LEN(@String)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n
FROM E4
)
SELECT COUNT(*) CharCount
FROM cteTally
WHERE SUBSTRING( @String, n, 1) LIKE @Pattern
GO
SELECT CharCount, COUNT(*)
FROM Table1
CROSS APPLY dbo.CountChars( ID, '[A-Za-Z]')
GROUP BY CharCount;
答案 3 :(得分:1)
使用NGrams8k,您可以这样做:
-- sample data
DECLARE @table TABLE(ID VARCHAR(30));
INSERT @table VALUES ('A00001'),('AB0001'),('AC123'),('CB00AD'),('1234AD');
-- Solution
WITH l(C) AS
(
SELECT Letters = SUM(PATINDEX('[A-Z]',ng.token))
FROM @table AS t
CROSS APPLY dbo.NGrams8k(t.ID,1) AS ng
GROUP BY t.ID
)
SELECT Letters = t.N,
RecordCount = COUNT(l.C)
FROM (VALUES(1),(2),(3),(4)) AS t(N)
LEFT JOIN l ON t.N = l.C
GROUP BY t.N;
返回:
Letters RecordCount
----------- -----------
1 1
2 3
3 0
4 1
答案 4 :(得分:0)
我知道,标量函数性能...为您提供了从字符串中剥离所有非Alpha字符的函数。取len()作为回报。其他评论是正确的,这不是明智的表现。
Create Function dbo.AlphaOnly ( @inStr varchar(max) )
Returns varchar(max)
as
Begin
Declare @curLoc int
Set @curLoc = PatIndex('%[^A-Za-z]%', @inStr)
While @curLoc > 0
Begin
Set @inStr = Stuff(@inStr,@curLoc,1,'')
Set @curLoc = PatIndex('%[^A-Za-z]%', @inStr)
End
Return @inStr
End
GO