在SQL中计算字符串中每个字母的出现次数

时间:2019-03-30 15:09:50

标签: sql-server

我有一个短语,例如“ BROWNSEA ISLAND”。 在MS SQL中,有没有一种方法可以导出一张表,该表显示字母出现的次数?例如:

B   1
R   1
O   1
W   1
N   2
S   2
E   1
etc....

2 个答案:

答案 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;

Demo

答案 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];