2012-09-10 10 views
118

Tengo una tabla como la siguiente:¿Cuenta el número de ocurrencias de una cadena en un campo VARCHAR?

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

Estoy tratando de encontrar la manera de devolver el número de veces que una cadena se produce en cada una de la descripción de.

Así, si quiero contar el número de veces que el 'valor' aparece, la instrucción SQL volverá esto:

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

¿Hay alguna manera de hacer esto? No quiero usar php, solo mysql.

+3

Las respuestas a continuación lo llevarán allí. Sin embargo, no olvides usar ['CHAR_LENGTH()'] (http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_char-length) en lugar de ['LENGTH () '] (http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_length) si está usando caracteres multibyte. – inhan

+0

Este hilo también ha sido respondido en [aquí] (https://stackoverflow.com/questions/5033047/mysql-query-finding-values-in-a-comma-separated-string/47069224#47069224) – Delickate

Respuesta

221

Esto debería hacer el truco:

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

Esta solución es increíble, justo lo que necesitaba! Pero tenga en cuenta que LENGTH() no es seguro en varios bytes y puede encontrarse con errores extraños.Use CHAR_LENGTH() en su lugar :) –

+0

no funciona cuando tiene palabras que contienen valor en ellas, p. "subestimar". La consulta también cuenta esta fila. – chyupa

+0

no hay diferencia en el uso de 'LENGTH()' y 'CHAR_LENGTH()' mientras se divide en el mismo byte de contaje/char. @nicogawenda – MohaMad

9

En SQL SERVER, esta es la respuesta

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 

Resultado

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

no tengo instalación de MySQL, pero Goggled Para encontrar el equivalente de LEN es LENGTH mientras REPLACE es mismo.

Así que la consulta equivalente en MySQL debe ser

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

Por favor, hágamelo saber si ha funcionado para usted en MySQL también.

12

intente esto:

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


SQL Fiddle Demo

1
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 

Gracias Yannis, su SOLUTIO n funcionó para mí y aquí estoy compartiendo la misma solución para varias palabras clave con orden y límite.

1

Aquí hay una función que hará eso.

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; 
6

Un poco más simple, pero más eficaz variación de @yannis solución:

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

La diferencia es que puedo reemplazar la cadena "valor" con una cadena de 1-char más corto ("1234" en este caso). De esta forma no es necesario dividir ni redondear para obtener un valor entero.

+1

¡Este es de hecho el mejor aquí! Gracias. –

Cuestiones relacionadas