231 votes

Compter le nombre d'occurrences d'une chaîne de caractères dans un champ VARCHAR ?

J'ai une table comme celle-ci :

TITLE          |   DESCRIPTION
------------------------------------------------
test1          |   value blah blah value
test2          |   value test
test3          |   test test test
test4          |   valuevaluevaluevaluevalue

J'essaie de trouver comment renvoyer le nombre de fois qu'une chaîne apparaît dans chacune des DESCRIPTION.

Ainsi, si je veux compter le nombre de fois où 'valeur' apparaît, l'instruction sql retournera ceci :

TITLE          |   DESCRIPTION                  |   COUNT
------------------------------------------------------------
test1          |   value blah blah value        |   2
test2          |   value test                   |   1
test3          |   test test test               |   0
test4          |   valuevaluevaluevaluevalue    |   5

Y a-t-il un moyen de le faire ? Je ne veux pas utiliser de php du tout, seulement mysql.

5 votes

Les réponses ci-dessous vous y conduiront. Cependant, n'oubliez pas d'utiliser CHAR_LENGTH() au lieu de LENGTH() si vous utilisez des caractères multi-octets.

0 votes

Ce fil a également été répondu sur ici

0 votes

Bonjour, comment puis-je faire cela avec sqlserver query ?

438voto

Yannis Points 1549

Cela devrait faire l'affaire :

SELECT 
    title,
    description,    
    ROUND (   
        (
            LENGTH(description)
            - LENGTH( REPLACE ( description, "value", "") ) 
        ) / LENGTH("value")        
    ) AS count    
FROM <table>

68 votes

Cette solution est géniale, juste ce dont j'avais besoin ! Mais notez que LENGTH() n'est pas sûr pour les octets multiples et vous pourriez rencontrer des erreurs étranges. Utilisez plutôt CHAR_LENGTH() :)

0 votes

Ne fonctionne pas lorsque vous avez des mots contenant une valeur, par exemple "undervalue". La requête compte également cette ligne.

2 votes

Il n'y a pas de différence dans l'utilisation de LENGTH() y CHAR_LENGTH() tout en divisant au même octet/char de comptage. @nicogawenda

52voto

GaborSch Points 6587

Une variante un peu plus simple et plus efficace de la solution de @yannis :

SELECT 
    title,
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH( REPLACE ( description, 'value', '1234') ) 
        AS `count`    
FROM <table> 

La différence est que je remplace la chaîne "valeur" par une chaîne plus courte d'un caractère ("1234" dans ce cas). De cette façon, vous n'avez pas besoin de diviser et d'arrondir pour obtenir une valeur entière.

Version généralisée (fonctionne pour toutes les chaînes d'aiguilles) :

SET @needle = 'value';
SELECT 
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH(REPLACE(description, @needle, SPACE(LENGTH(@needle)-1))) 
        AS `count`    
FROM <table>

2 votes

+1 pour l'idée, bien que je préfère généralement les implémentations évidentes, c'est-à-dire qui ne nécessitent pas d'explication supplémentaire, même si elles semblent moins élégantes.

26voto

Joe G Joseph Points 12384

Essayez ceci :

 select TITLE,
        (length(DESCRIPTION )-length(replace(DESCRIPTION ,'value','')))/5 as COUNT 
  FROM <table> 

Démonstration de SQL Fiddle

3 votes

La longueur n'est pas sûre en binaire, utilisez char_length()

15voto

Niladri Biswas Points 4173

Dans SQL SERVER, voici la réponse

Declare @t table(TITLE VARCHAR(100), DESCRIPTION VARCHAR(100))

INSERT INTO @t SELECT 'test1', 'value blah blah value' 
INSERT INTO @t SELECT 'test2','value test' 
INSERT INTO @t SELECT 'test3','test test test' 
INSERT INTO @t SELECT 'test4','valuevaluevaluevaluevalue' 

SELECT TITLE,DESCRIPTION,Count = (LEN(DESCRIPTION) - LEN(REPLACE(DESCRIPTION, 'value', '')))/LEN('value') 

FROM @t

Résultat

TITLE   DESCRIPTION               Count
test1   value blah blah value        2
test2   value test                   1
test3   test test test               0
test4   valuevaluevaluevaluevalue    5

Je n'ai pas installé MySQL, mais j'ai cherché à trouver l'équivalent de LEN. LONGUEUR tandis que REMPLACER est le même.

Donc la requête équivalente en MySql devrait être

SELECT TITLE,DESCRIPTION, (LENGTH(DESCRIPTION) - LENGTH(REPLACE(DESCRIPTION, 'value', '')))/LENGTH('value') AS Count
FROM <yourTable>

Veuillez me faire savoir si cela a fonctionné pour vous dans MySql également.

6voto

michaelbn Points 1388

Voici une fonction qui permet de le faire.

CREATE FUNCTION count_str(haystack TEXT, needle VARCHAR(32))
  RETURNS INTEGER DETERMINISTIC
  BEGIN
    RETURN ROUND((CHAR_LENGTH(haystack) - CHAR_LENGTH(REPLACE(haystack, needle, ""))) / CHAR_LENGTH(needle));
  END;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X