Une fonction de comptage d’occurrence

La petite fonction qui suit permet de compter le nombre de fois ou un caractère est présent dans une chaine de caractères.

CREATE FUNCTION F_COUNT_CHAR(@STR NVARCHAR(MAX), @CHR NCHAR(1))
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE @NBR INT, @POS INT;
SELECT @NBR = 0, @POS = CHARINDEX(@CHR, @STR);
WHILE @POS > 0
BEGIN
   SET @NBR = @NBR + 1;
   SET @POS = CHARINDEX(@CHR, @STR, @POS + 1);
END;
RETURN @NBR;
END;
GO

Exemples d’utilisation :

-- exemple                                  -- résultat
------------------------------------------- ------------

SELECT dbo.F_COUNT_CHAR('abracadabra', 'a') --> 5

SELECT dbo.F_COUNT_CHAR('', 'a')            --> 0
SELECT dbo.F_COUNT_CHAR('a', '')            --> 0
SELECT dbo.F_COUNT_CHAR('', '')             --> 0

SELECT dbo.F_COUNT_CHAR(NULL, 'a')          --> NULL
SELECT dbo.F_COUNT_CHAR('a', NULL)          --> NULL
SELECT dbo.F_COUNT_CHAR(NULL, NULL)         --> NULL
Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES
Expert  S.G.B.D  relationnelles   et   langage  S.Q.L
Moste  Valuable  Professionnal  Microsoft  SQL Server
Société SQLspot  :  modélisation, conseil, formation,
optimisation,  audit,  tuning,  administration  SGBDR
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.

L’entreprise SQL Spot
Le site web sur le SQL et les SGBDR

MVP Microsoft SQL
Server

Développez et administrez pour la performance avec SQL Server 2014

Développez et administrez pour la performance avec SQL Server 2014

2 réflexions au sujet de « Une fonction de comptage d’occurrence »

  1. Avatar de SQLproSQLpro Auteur de l’article

    Aussi astucieuse soit-elle cette solution est moins rapide…
    Voici mes tests :
    la mienne rectifiée :

    CREATE FUNCTION F_COUNT_CHAR_(@STR NVARCHAR(MAX), @CHR NVARCHAR(max))
    RETURNS INT
    WITH RETURNS NULL ON NULL INPUT
    AS
    BEGIN
    DECLARE @NBR INT, @POS INT;
    SELECT @NBR = 0, @POS = CHARINDEX(@CHR, @STR);
    WHILE @POS > 0
    BEGIN
       SET @NBR = @NBR + 1;
       SET @POS = CHARINDEX(@CHR, @STR, @POS + LEN(@CHR));
    END;
    RETURN @NBR;
    END;
    GO

    Sur 1 250 000 lignes : Temps UC = 4844 ms, temps écoulé = 6206 ms.

    La vôtre rectifiée :

    CREATE FUNCTION F_COUNT_CHAR(@STR NVARCHAR(MAX), @CHR NVARCHAR(MAX))
    RETURNS INT
    WITH RETURNS NULL ON NULL INPUT
    AS
    BEGIN
    DECLARE @NBR INT, @STR2 NVARCHAR(MAX)
    SELECT @NBR = IIF(LEN(ISNULL(@CHR,''))=0,0, (LEN(@STR)-LEN(REPLACE(@STR, @CHR,''))) / LEN(@CHR))
    RETURN @NBR;
    END;
    GO

    Sur le même panel de lignes : Temps UC = 6969 ms, temps écoulé = 8022 ms.

  2. Avatar de FMJFMJ

    Bonjour,
    Petite astuce : Plutôt que de faire une boucle, je fais plutôt ceci en une seule ligne.
    A noter que cette fonction permet aussi le dénombrable d’une chaîne (@CHR peut faire plusieurs caractères). Et gère le cas où @CHR est nul ou de longueur nulle.

    CREATE FUNCTION F_COUNT_CHAR(@STR NVARCHAR(MAX), @CHR NCHAR(MAX))
    RETURNS INT
    WITH RETURNS NULL ON NULL INPUT
    AS
    BEGIN
    DECLARE @NBR INTn @STR2 NVARCHAR(MAX)
    SELECT@NBR = IIF(LEN(ISNULL(@CHR,''))=0,0, (LEN(@STR)-LEN(REPLACE(@STR, @CHR,''))) / LEN(@CHR))
    RETURN @NBR;
    END;
    GO

Laisser un commentaire