A consulta MySQL String contém

307

Eu tenho tentado descobrir como posso fazer uma consulta com o MySQL que verifica se o valor (string $haystack) em uma determinada coluna contém certos dados (string $needle), assim:

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

No PHP, a função é chamada substr($haystack, $needle), então talvez:

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

Respostas:

437

Muito simples, na verdade:

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

O %é um curinga para qualquer conjunto de caracteres (nenhum, um ou muitos). Observe que isso pode ficar lento em conjuntos de dados muito grandes, portanto, se seu banco de dados crescer, você precisará usar índices de texto completo.

Wolph
fonte
1
Isso só funcionará se você estiver usando uma consulta preparada. Se você estiver usando uma string real (por exemplo, script de atualização do liquibase sql), considere o INSTR mencionado abaixo). Isso ocorre porque, se sua string contiver%, você começará a combinar as coisas com ela.
Ryan Shillington
2
eu sei como consultas, e ainda hoje eu queria descobrir se existe algum valor em string em alguma coluna que eu estava pesquisando por isso .. Por que nunca pensei nisso antes?
Código Sizzling
1
este caso é sensível?
kiwi irritado
2
@angry_kiwi: com column LIKE '...'ele é insensível caso, com column LIKE BINARY '...'ele é sensível a maiúsculas
Wolph
2
Estou surpreso que LIKEseja proposto verificar qualquer substring, pois esse operador usa dois caracteres curinga: %e _. Isso significa que, se sua string $ needle contiver um desses caracteres especiais, os resultados não serão os esperados. (-1) para esta resposta e (+1) para a resposta INSTR.
Skrol29
144

Usar:

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

Referência:

Pôneis OMG
fonte
certamente LIKE é mais rápido que o INSTR?
chris
17
@ oedo: Depende. LIKE %...%não usará um índice se houver algum, portanto eles devem ser equivalentes; LIKE ...%usaria um índice se presente. Se o desempenho for uma preocupação real, a Pesquisa de Texto Completo (STF) seria uma abordagem melhor.
OMG Ponies
perfeito. exatamente o que eu estava procurando.
quer
2
Eu gosto dessa solução, pois, de fato, não há como classificar as coisas de acordo com a presença de uma substring com o likeoperador. Com instruma frase pode ser ordenada desta formaselect * from table order by instr(col1,"mystring")
Radacina 01/08/19
Eu queria procurar _ em um campo e funcionou. Obrigado
Safeer Ahmed
53
WHERE `column` LIKE '%$needle%'
chris
fonte
2
quando procurar o personagem _ (sublinhado) '% _%' a consulta como não funcionar, por algum motivo, ele retorna todas as cordas mesmo sem _
Wojtek
1
@Wojtek _ é um curinga para qualquer caractere único; portanto, se você quiser procurar um sublinhado literal, precisará escapar dele. Veja MySQL LIKE query com sublinhado .
Jkmartindale
29

O meu está usando LOCATEno mysql:

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

Essa função é segura para vários bytes e diferencia maiúsculas de minúsculas se pelo menos um argumento for uma sequência binária.

No seu caso:

mysql_query("
SELECT * FROM `table`
WHERE LOCATE('{$needle}','column') > 0
");
risnandar
fonte
11
'coluna' deve ser de coluna (sem aspas)
Wojtek
10

Além da resposta de @WoLpH.

Ao usar a LIKEpalavra-chave, você também pode limitar em qual direção a string corresponde. Por exemplo:

Se você estava procurando por uma sequência que comece com o seu $needle:

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

Se você estava procurando uma sequência que termina com $needle:

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

esteja ciente de que isso é perigoso:

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

faça primeiro:

$needle = mysql_real_escape_string($needle);

para evitar possíveis ataques.

Alejandro Moreno
fonte
7
* Alguns ataques possíveis. Além disso, mysql_real_escape_stringserá preterido em versões futuras do PHP.
Jack Tuck
11
Você deve usar instruções preparadas e deixar o escape para o PHP. $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
cloudworks
3

Você provavelmente está procurando find_in_setfunção:

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

Esta função atua como in_arrayfunção no PHP

Andres
fonte