La chaîne de requête MySQL contient


307

J'ai essayé de comprendre comment je peux faire une requête avec MySQL qui vérifie si la valeur (chaîne $haystack) dans une certaine colonne contient certaines données (chaîne $needle), comme ceci:

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

En PHP, la fonction est appelée substr($haystack, $needle), alors peut-être:

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

Réponses:


437

Assez simple en fait:

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

Le %est un caractère générique pour n'importe quel jeu de caractères (aucun, un ou plusieurs). Notez que cela peut devenir lent sur de très grands ensembles de données, donc si votre base de données grandit, vous devrez utiliser des indices de texte intégral.


1
Cela ne fonctionnera que si vous utilisez une requête préparée. Si vous utilisez une chaîne réelle (par exemple, un script de mise à niveau sql liquibase), considérez INSTR comme mentionné ci-dessous). En effet, si votre chaîne contient un%, vous commencerez à faire correspondre les choses avec.
Ryan Shillington

2
je connais des requêtes similaires, et pourtant aujourd'hui je voulais savoir si une certaine valeur existe dans une chaîne dans une colonne, je cherchais pour ça .. Pourquoi je n'y avais jamais pensé avant ??
Code grésillant du

1
cette casse est-elle sensible?
kiwi en colère

2
@angry_kiwi: avec column LIKE '...'elle est insensible à la casse, avec column LIKE BINARY '...'elle est sensible à la casse
Wolph

2
Je suis surpris qu'il LIKEsoit proposé de vérifier toute sous-chaîne car cet opérateur utilise deux caractères génériques: %et _. Cela signifie que si votre chaîne $ needle contient l'un de ces caractères spéciaux, le résultat n'est pas du tout attendu. (-1) pour cette réponse et (+1) pour la réponse INSTR.
Skrol29

144

Utilisation:

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

Référence:


LIKE est sûrement plus rapide que INSTR?
chris

17
@oedo: Ça dépend. LIKE %...%n'utilisera pas d'index s'il en existe un, ils devraient donc être équivalents; LIKE ...%utiliserait un index s'il était présent. Si les performances sont un réel problème, la recherche en texte intégral (FTS) serait une meilleure approche.
OMG Ponies

parfait. juste ce que je cherchais.
arik

2
J'aime cette solution car en fait il n'y a aucun moyen de trier les choses en fonction de la présence d'une sous-chaîne avec likeopérateur. Avec instrune phrase peut être commandée comme ceciselect * from table order by instr(col1,"mystring")
Radacina

Je voulais rechercher _ dans un champ et cela a fonctionné. Merci
Safeer Ahmed

53
WHERE `column` LIKE '%$needle%'

2
lors de la recherche du caractère _ (souligné), la requête LIKE '% _%' ne fonctionne pas, pour une raison quelconque, elle renvoie toutes les chaînes même sans _
Wojtek

1
@Wojtek _ est un caractère générique pour n'importe quel caractère, donc si vous voulez rechercher un trait de soulignement littéral, vous devrez l'échapper. Voir Requête LIKE MySQL avec trait de soulignement .
jkmartindale

29

Le mien utilise LOCATEdans mysql:

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

Cette fonction est sûre sur plusieurs octets et ne respecte la casse que si au moins un argument est une chaîne binaire.

Dans ton cas:

mysql_query("
SELECT * FROM `table`
WHERE LOCATE('{$needle}','column') > 0
");

11
'colonne' doit être une colonne (sans guillemets)
Wojtek

10

En plus de la réponse de @WoLpH.

Lorsque vous utilisez le LIKEmot - clé, vous avez également la possibilité de limiter la direction dans laquelle la chaîne correspond. Par exemple:

Si vous cherchiez une chaîne commençant par votre $needle:

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

Si vous cherchiez une chaîne qui se termine par $needle:

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

3

sachez que cela est dangereux:

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

faire en premier:

$needle = mysql_real_escape_string($needle);

il empêchera ainsi d'éventuelles attaques.


7
* Quelques attaques possibles. En outre, mysql_real_escape_stringva être obsolète dans les futures versions de PHP.
Jack Tuck

11
Vous devez utiliser des instructions préparées et laisser l'échappement à PHP. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
cloudworks

3

Vous recherchez probablement une find_in_setfonction:

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

Cette fonction agit comme une in_arrayfonction en PHP

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.