我有一个短语,例如“ BROWNSEA ISLAND”。 在MS SQL中,有没有一种方法可以导出一张表,该表显示字母出现的次数?例如:
B 1
R 1
O 1
W 1
N 2
S 2
E 1
etc....
答案 0 :(得分:1)
您可以创建一个包含所有字母的日历表,然后进行联接:
WITH letters AS (
SELECT 'A' AS letter UNION ALL
SELECT 'B' UNION ALL
SELECT 'C' UNION ALL
...
SELECT 'Z'
)
SELECT
letter,
LEN('BROWNSEA ISLAND') - LEN(REPLACE('BROWNSEA ISLAND', letter, '')) AS count
FROM letters
ORDER BY
letter;
答案 1 :(得分:1)
在大多数现代版本的SQL Server上,
DECLARE @s varchar(255) = 'BROWNSEA ISLAND';
;WITH n(n) AS
(
SELECT 1 UNION ALL SELECT n+1 FROM n WHERE n < LEN(@s)
)
SELECT
Letter = SUBSTRING(@s,n,1),
Occurs = COUNT(*) OVER (PARTITION BY SUBSTRING(@s,n,1))
FROM n
ORDER BY n;
除了字母之外,还将计算空格,数字和非字母数字字符。如果您想保留这些计数NULL
,则可以说:
DECLARE @s varchar(255) = 'BROWNSEA ISLAND';
;WITH n(n) AS
(
SELECT 1 UNION ALL SELECT n+1 FROM n WHERE n < LEN(@s)
),
l AS
(
SELECT n, Letter = SUBSTRING(@s,n,1) FROM n
)
SELECT Letter, Occurs = CASE
WHEN ASCII(Letter) BETWEEN 65 AND 90
OR ASCII(Letter) BETWEEN 97 AND 122
THEN COUNT(*) OVER (PARTITION BY Letter)
END
FROM l ORDER BY n;
如果要忽略这些内容,可以将CASE
表达式移至WHERE
子句。如果您希望大写的Z
和小写的z
进行计数,请告诉我们。
如果要在函数中使用它,以便可以将其应用于多个行中的多个值,而不是单个变量:
CREATE FUNCTION dbo.CountLetters(@s nvarchar(255))
RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
(
WITH n(n) AS
(
SELECT 1 UNION ALL SELECT n+1 FROM n WHERE n < LEN(@s)
)
SELECT [Rank] = n,
Letter = SUBSTRING(@s,n,1),
Occurs = COUNT(*) OVER (PARTITION BY SUBSTRING(@s,n,1))
FROM n
);
GO
样品用量:
SELECT o.name, f.[Rank], f.Letter, f.Occurs
FROM sys.objects AS o
CROSS APPLY dbo.CountLetters(name) AS f
ORDER BY o.name, f.[Rank];