Anzahl der Vorkommen einer Zeichenfolge in einem VARCHAR-Feld zählen?

175

Ich habe einen Tisch wie diesen:

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

Ich versuche herauszufinden, wie oft eine Zeichenfolge in jeder der BESCHREIBUNGEN vorkommt.

Wenn ich also zählen möchte, wie oft 'Wert' angezeigt wird, gibt die SQL-Anweisung Folgendes zurück:

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

Gibt es eine Möglichkeit, dies zu tun? Ich möchte überhaupt kein PHP verwenden, nur MySQL.

Geekman
quelle
4
Die folgenden Antworten bringen Sie dorthin. Vergessen Sie jedoch nicht, CHAR_LENGTH()anstelle von LENGTH()Multibyte-Zeichen zu verwenden.
Inhan
Dieses Thema wurde auch beantwortet über hier
Delickate
Hallo, wie mache ich das mit der SQL Server-Abfrage?
aintno12u
LÄNGE ([Feld]) - LÄNGE (ERSETZEN ([Feld], '[char_to_find]', ''))
Phoenix

Antworten:

343

Dies sollte den Trick tun:

SELECT 
    title,
    description,    
    ROUND (   
        (
            LENGTH(description)
            - LENGTH( REPLACE ( description, "value", "") ) 
        ) / LENGTH("value")        
    ) AS count    
FROM <table> 
Yannis
quelle
55
Diese Lösung ist fantastisch, genau das, was ich brauchte! Beachten Sie jedoch, dass LENGTH () nicht mehrbyte-sicher ist und möglicherweise seltsame Fehler auftreten. Verwenden Sie stattdessen CHAR_LENGTH () :)
Nico Gawenda
1
Es gibt keinen Unterschied bei der Verwendung von LENGTH()und CHAR_LENGTH()während der Aufteilung auf dasselbe Zählbyte / Zeichen. @nicogawenda
MohaMad
3
@chyupa undevaluehaben valuedrin, also sollte es gezählt werden. Wenn Sie nur vollständige Wörter zählen möchten, müssen Sie möglicherweise nach 'Wert' suchen oder etwas Komplizierteres wie die Verwendung von Regex verbessern.
PhoneixS
2
Beachten Sie, dass Sie beim Durchsuchen von Text, der auch Wörter mit Großbuchstaben enthält, auf falsche Zählungen stoßen (wie Deutsch, bei dem alle Substantive mit Großbuchstaben geschrieben sind). Der REPLACE ersetzt nur exakte Übereinstimmungen. Um alle Wörter zu berücksichtigen, müssen Sie den obigen Ersatz in: ändern LENGTH( REPLACE ( LOWER(description), "value", "") )und sicherstellen, dass "Wert" durch Verwendung von PHP immer in Kleinbuchstaben geschrieben wird strtolower(). PS: Diese obige Lösung hat mir geholfen, meine eigene kleine Suchmaschine aufzubauen und die Ergebnisse mit der Anzahl der Wörter im Text zu gewichten. Vielen Dank!
Kai Noack
2
Das ROUNDhier ist unnötig. Nehmen Sie eine Zeichenfolge xmit einem nVorkommen von an 'value. LENGTH(description) - LENGTH( REPLACE ( description, "value", "") ) wird dir immer geben n*length("value"), Tauchen, das nach Länge des Wertes immer eine ganze Zahl hinterlässt n. Keine Notwendigkeit
abzurunden
21

Eine etwas einfachere und effektivere Variante der @ yannis-Lösung:

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

Der Unterschied besteht darin, dass ich die Zeichenfolge "value" durch eine kürzere Zeichenfolge mit 1 Zeichen ersetze (in diesem Fall "1234"). Auf diese Weise müssen Sie nicht teilen und runden, um einen ganzzahligen Wert zu erhalten.

Verallgemeinerte Version (funktioniert für jede Nadelschnur):

SET @needle = 'value';
SELECT 
    description,    
    CHAR_LENGTH(description) - CHAR_LENGTH(REPLACE(description, @needle, SPACE(LENGTH(@needle)-1))) 
        AS `count`    
FROM <table> 
gaborsch
quelle
1
+1 für die Idee, obwohl ich im Allgemeinen offensichtliche Implementierungen bevorzuge, dh die keiner zusätzlichen Erklärung bedürfen, auch wenn sie weniger elegant aussehen.
not2savvy
19

Versuche dies:

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


SQL Fiddle Demo

Joe G Joseph
quelle
2
Länge ist nicht binär sicher, verwenden Sie char_length ()
luky
12

In SQL Server ist dies die Antwort

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

Ergebnis

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

Ich habe MySQL nicht installiert, aber ich habe goggled, um herauszufinden, dass das Äquivalent von LEN LENGTH ist, während REPLACE dasselbe ist.

Die entsprechende Abfrage in MySql sollte also lauten

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

Bitte lassen Sie mich wissen, ob es auch in MySql für Sie funktioniert hat.

Niladri Biswas
quelle
3

Hier ist eine Funktion, die das macht.

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;
Michaelbn
quelle
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

Vielen Dank, Yannis, Ihre Lösung hat für mich funktioniert und hier teile ich dieselbe Lösung für mehrere Keywords mit Reihenfolge und Limit.

Trimantra-Softwarelösung
quelle
1

Dies ist die MySQL-Funktion unter Verwendung der Raumfahrttechnik (getestet mit 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)) );

jfx
quelle