La cadena de consulta MySQL contiene


307

He estado tratando de descubrir cómo puedo hacer una consulta con MySQL que verifique si el valor (cadena $haystack) en una determinada columna contiene ciertos datos (cadena $needle), como este:

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

En PHP, la función se llama substr($haystack, $needle), así que tal vez:

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

Respuestas:


437

Bastante simple en realidad:

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

El %es un comodín para cualquier conjunto de caracteres (ninguno, uno o muchos). Tenga en cuenta que esto puede ser lento en conjuntos de datos muy grandes, por lo que si su base de datos crece, deberá usar índices de texto completo.


1
Esto solo funcionará si está utilizando una consulta preparada. Si está usando una cadena real allí (por ejemplo, script de actualización de liquibase sql), considere INSTR mencionado a continuación). Esto se debe a que si su cadena contiene un%, comenzará a hacer coincidir las cosas con ella.
Ryan Shillington

2
Sé acerca de consultas similares, y sin embargo, hoy quería saber si existe cierto valor en la cadena en alguna columna que estaba buscando en Google. ¿Por qué nunca pensé en eso antes?
Código chisporroteo

1
¿Es este caso sensible?
Kiwi enojado

2
@angry_kiwi: con column LIKE '...'mayúsculas y minúsculas, con column LIKE BINARY '...'mayúsculas y minúsculas
Wolph

2
Me sorprende que LIKEse proponga verificar cualquier subcadena ya que este operador utiliza dos caracteres comodín: %y _. Esto significa que si su cadena $ needle contiene uno de estos caracteres especiales, los resultados no son los esperados. (-1) para esta respuesta y (+1) para la respuesta INSTR.
Skrol29

144

Utilizar:

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

Referencia:


seguramente LIKE es más rápido que INSTR?
Chris

17
@Oedo: Depende. LIKE %...%no usará un índice si hay uno presente, por lo que deberían ser equivalentes; LIKE ...%usaría un índice si está presente. Si el rendimiento es una preocupación real, la búsqueda de texto completo (FTS) sería un mejor enfoque.
OMG Ponis

Perfecto. Justo lo que estaba buscando.
arik

2
Me gusta esta solución, ya que de hecho no hay forma de ordenar las cosas según la presencia de una subcadena con el likeoperador. Con instruna frase se puede ordenar asíselect * from table order by instr(col1,"mystring")
Radacina

Quería buscar _ en un campo y funcionó. Gracias
Safeer Ahmed

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

2
al buscar el carácter _ (guión bajo) la consulta LIKE '% _%' no funciona, por alguna razón devuelve todas las cadenas incluso sin _
Wojtek

1
@Wojtek _ es un comodín para cualquier carácter individual, por lo que si desea buscar un guión bajo literal, deberá escapar de él. Vea la consulta MySQL LIKE con guión bajo .
jkmartindale

29

El mío está usando LOCATEen mysql:

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

Esta función es segura para varios bytes y distingue entre mayúsculas y minúsculas solo si al menos un argumento es una cadena binaria.

En tu caso:

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

11
'column' debe ser column (sin comillas)
Wojtek

10

Además de la respuesta de @WoLpH.

Al usar la LIKEpalabra clave, también tiene la capacidad de limitar en qué dirección coincide la cadena. Por ejemplo:

Si estabas buscando una cadena que comience con tu $needle:

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

Si estabas buscando una cadena que termina con $needle:

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

3

Tenga en cuenta que esto es peligroso:

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

hacer primero:

$needle = mysql_real_escape_string($needle);

así evitará posibles ataques.


77
* Algunos posibles ataques. Además, mysql_real_escape_stringquedará en desuso en futuras versiones de PHP.
Jack Tuck

11
Debe usar declaraciones preparadas y dejar el escape a PHP. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
cloudworks

3

Probablemente estés buscando la find_in_setfunción:

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

Esta función actúa como in_arrayfunción en PHP

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.