web-dev-qa-db-fra.com

Compter le nombre d'occurrences d'une chaîne 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 comprendre comment renvoyer le nombre d'occurrences d'une chaîne dans chacune des descriptions.

Donc, si je veux compter le nombre de fois où 'valeur' ​​apparaît, l'instruction sql renverra 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 faire ça? Je ne veux pas utiliser php du tout, juste mysql.

147
Geekman

Cela devrait faire l'affaire:

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

essaye ça:

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


Démo SQL Fiddle

14
Joe G Joseph

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 je dois trouver l'équivalent de LEN comme suit: LENGTH while REPLACE est identique.

Donc, la requête équivalente dans MySql devrait être

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

S'il vous plaît laissez-moi savoir si cela a fonctionné pour vous dans MySql également.

10
Niladri Biswas

Variation un peu plus simple et plus efficace de la solution @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 de 1 caractère ("1234" dans ce cas). De cette façon, vous n'avez pas besoin de diviser et arrondir pour obtenir une valeur entière.

Version généralisée (fonctionne pour chaque chaîne d'aiguille):

SET @needle = 'value';
SELECT 
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH(REPLACE(description, @needle, SPACE(LENGTH(@needle)-1))) 
        AS `count`    
FROM <table> 
10
gaborsch
SELECT 
id,
jsondata,    
ROUND (   
    (
        LENGTH(jsondata)
        - LENGTH( REPLACE ( jsondata, "sonal", "") ) 
    ) / LENGTH("sonal")        
)
+
ROUND (   
    (
        LENGTH(jsondata)
        - LENGTH( REPLACE ( jsondata, "khunt", "") ) 
    ) / LENGTH("khunt")        
)
AS count1    FROM test ORDER BY count1 DESC LIMIT 0, 2

Merci Yannis, votre solution a fonctionné pour moi et je partage ici la même solution pour plusieurs mots clés avec ordre et limite.

Voici une fonction qui fera cela.

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;
1
michaelbn

Voici la fonction mysql utilisant la technique d'espace (testée avec mysql 5.0 + 5.5): CREATE FUNCTION count_str( haystack TEXT, needle VARCHAR(32)) RETURNS INTEGER DETERMINISTIC RETURN LENGTH(haystack) - LENGTH( REPLACE ( haystack, needle, space(char_length(needle)-1)) );

0
jfx