MySQL-Abfragezeichenfolge enthält

307

Ich habe versucht herauszufinden, wie ich mit MySQL eine Abfrage durchführen kann, die prüft, ob der Wert (Zeichenfolge $haystack) in einer bestimmten Spalte bestimmte Daten (Zeichenfolge $needle) enthält, wie folgt:

mysql_query("
SELECT *
FROM `table`
WHERE `column`.contains('{$needle}')
");

In PHP wird die Funktion aufgerufen substr($haystack, $needle), also vielleicht:

WHERE substr(`column`, '{$needle}')=1
arik
quelle

Antworten:

437

Ganz einfach:

mysql_query("
SELECT *
FROM `table`
WHERE `column` LIKE '%{$needle}%'
");

Dies %ist ein Platzhalter für einen beliebigen Zeichensatz (keiner, einer oder viele). Beachten Sie, dass dies bei sehr großen Datenmengen langsam werden kann. Wenn Ihre Datenbank wächst, müssen Sie Volltextindizes verwenden.

Wolph
quelle
1
Dies funktioniert nur, wenn Sie eine vorbereitete Abfrage verwenden. Wenn Sie dort eine tatsächliche Zeichenfolge verwenden (z. B. Liquibase-SQL-Upgrade-Skript), ziehen Sie INSTR in Betracht (siehe unten). Dies liegt daran, dass Sie, wenn Ihre Zeichenfolge ein% enthält, damit beginnen, Dinge damit abzugleichen.
Ryan Shillington
2
Ich weiß über ähnliche Abfragen Bescheid, und doch wollte ich heute herausfinden, ob in einer Spalte, in der ich gegoogelt habe, ein bestimmter Wert in einer Zeichenfolge vorhanden ist. Warum habe ich noch nie daran gedacht?
Sizzling Code
1
Ist dieser Fall sensibel?
wütend Kiwi
2
@angry_kiwi: mit column LIKE '...'ihm ist Groß- und Kleinschreibung, mit column LIKE BINARY '...'ihm Groß- und Kleinschreibung
Wolph
2
Ich bin überrascht, dass LIKEvorgeschlagen wird, nach Teilzeichenfolgen zu suchen, da dieser Operator zwei Platzhalterzeichen verwendet: %und _. Das heißt, wenn Ihre Zeichenfolge $ Nadel eines dieser Sonderzeichen enthält, sind die Ergebnisse überhaupt nicht wie erwartet. (-1) für diese Antwort und (+1) für die INSTR-Antwort.
Skrol29
144

Verwenden:

SELECT *
  FROM `table`
 WHERE INSTR(`column`, '{$needle}') > 0

Referenz:

OMG Ponys
quelle
sicherlich ist LIKE schneller als INSTR?
chris
17
@oedo: Kommt darauf an. LIKE %...%verwendet keinen Index, wenn einer vorhanden ist, daher sollten sie gleichwertig sein; LIKE ...%würde einen Index verwenden, falls vorhanden. Wenn die Leistung ein echtes Problem darstellt, ist die Volltextsuche (FTS) ein besserer Ansatz.
OMG Ponys
perfekt. genau das, wonach ich gesucht habe.
Arik
2
Ich mag diese Lösung, da es tatsächlich keine Möglichkeit gibt, Dinge nach dem Vorhandensein eines Teilstrings mit likeOperator zu sortieren . Mit instreinem Satz kann so bestellt werdenselect * from table order by instr(col1,"mystring")
Radacina
Ich wollte in einem Feld nach _ suchen und es hat funktioniert. Danke
Safeer Ahmed
53
WHERE `column` LIKE '%$needle%'
chris
quelle
2
Bei der Suche nach dem Zeichen _ (Unterstrich) funktioniert die Abfrage LIKE '% _%' nicht. Aus irgendeinem Grund werden alle Zeichenfolgen auch ohne _ zurückgegeben
Wojtek
1
@Wojtek _ ist ein Platzhalter für ein einzelnes Zeichen. Wenn Sie also nach einem wörtlichen Unterstrich suchen möchten, müssen Sie ihn maskieren. Siehe MySQL LIKE-Abfrage mit Unterstrich .
Jkmartindale
29

Meins verwendet LOCATEin MySQL:

LOCATE (substr, str), LOCATE (substr, str, pos)

Diese Funktion ist mehrbyte-sicher und unterscheidet nur zwischen Groß- und Kleinschreibung, wenn mindestens ein Argument eine Binärzeichenfolge ist.

In deinem Fall:

mysql_query("
SELECT * FROM `table`
WHERE LOCATE('{$needle}','column') > 0
");
Risnandar
quelle
11
'Spalte' sollte Spalte sein (ohne Anführungszeichen)
Wojtek
10

Neben der Antwort von @WoLpH.

Wenn Sie das LIKESchlüsselwort verwenden, können Sie auch die Richtung einschränken, in die die Zeichenfolge passt. Zum Beispiel:

Wenn Sie nach einer Zeichenfolge suchen, die mit Ihrer beginnt $needle:

... WHERE column LIKE '{$needle}%'

Wenn Sie nach einer Zeichenfolge suchen, die mit folgendem endet $needle:

... WHERE column LIKE '%{$needle}'
Joshua Powell
quelle
3

Beachten Sie, dass dies gefährlich ist:

WHERE `column` LIKE '%{$needle}%'

zuerst tun:

$needle = mysql_real_escape_string($needle);

So werden mögliche Angriffe verhindert.

Alejandro Moreno
quelle
7
* Einige mögliche Angriffe. Auch mysql_real_escape_stringwird in zukünftigen PHP-Versionen veraltet sein.
Jack Tuck
11
Sie sollten vorbereitete Anweisungen verwenden und die Übergabe PHP überlassen. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
Cloudworks
3

Sie suchen wahrscheinlich nach find_in_setFunktion:

Where find_in_set($needle,'column') > 0

Diese Funktion verhält sich wie eine in_arrayFunktion in PHP

Andres
quelle