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.