Como posso pesquisar (sem distinção entre maiúsculas e minúsculas) em uma coluna usando o curinga LIKE?


289

Olhei em volta e não encontrei o que estava procurando, então aqui vai.

SELECT * FROM trees WHERE trees.`title` LIKE  '%elm%'

Isso funciona bem, mas não se a árvore for denominada Elm ou ELM, etc.

Como faço para não fazer distinção entre maiúsculas e minúsculas SQL para esta pesquisa de caracteres curinga?

Estou usando o MySQL 5 e o Apache.


3
Se você tropeçou nesta página, mas suas configurações MySql fazer um trabalho sobre esta consulta para Elm ou ELM e você quer que ele seja sensível a maiúsculas, veja BINARYcomo aqui: stackoverflow.com/questions/7857669/...
joshuahedlund

Não depende do agrupamento de campo / tabela? like 'ut8_general_CI'
Yousha Aleayoub

Como usá-lo seqüenciar consulta de nó?
Ashh

O MySQL likedeve diferenciar maiúsculas de minúsculas por padrão.
Marko Bonaci 28/04

Respostas:


281
SELECT  *
FROM    trees
WHERE   trees.`title` COLLATE UTF8_GENERAL_CI LIKE '%elm%'

Na verdade, se você adicionar COLLATE UTF8_GENERAL_CIà definição da sua coluna, poderá omitir todos esses truques: ele funcionará automaticamente.

ALTER TABLE trees 
 MODIFY COLUMN title VARCHAR(…) CHARACTER 
 SET UTF8 COLLATE UTF8_GENERAL_CI. 

Isso também reconstruirá quaisquer índices nessa coluna para que eles possam ser usados ​​para as consultas sem levar '%'


34
Na verdade, se você adicionar COLLATE UTF8_GENERAL_CIà definição da sua coluna, poderá omitir todos esses truques: ele funcionará automaticamente. ALTER TABLE trees MODIFY COLUMN title VARCHAR(…) CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI. Isso também reconstruirá quaisquer índices nesta coluna para que eles possam ser usados ​​para as consultas sem levar '%'.
Quassnoi 20/05

1
ALTER TABLE trees MODIFY COLUMN title VARCHAR (...) esta parece a melhor maneira, muito obrigado ... deixe o sql fazer o trabalho
David Morrow

10
Lembrete amigável de que esta é uma resposta mysql. Se você estiver usando o PostgreSQL, o ILike é a solução para a pergunta acima.
Steve

2
@RajanRawal: envie sua pergunta como uma pergunta, não como um comentário. Obrigado.
Quassnoi

1
Esta é a resposta correta, desde que o seu agrupamento original seja geral, não bin.
greenoldman

261

Eu sempre resolvi isso usando menor:

SELECT * FROM trees WHERE LOWER( trees.title ) LIKE  '%elm%'

47
e use o índice de deterioração
Seu senso comum

3
O MySQL 5 possui um operador ILIKE?
Luke Maurer

27
embora para a pesquisa %% não importe de qualquer maneira :)
Seu senso comum

5
@Col. - É certo que isso não é o ideal para colunas indexadas, mas funcionará para uma estrutura que já está em vigor. Também descobri que as pesquisas que não diferenciam maiúsculas de minúsculas são mais comuns em colunas que não são indexadas de qualquer maneira.
Cwallenpoole 20/05

1
O agrupamento padrão já é IC. Portanto, o verdadeiro problema não está nesta questão em particular. Mas ainda é uma resposta perfeita no estilo SO.
Seu senso comum

48

A distinção entre maiúsculas e minúsculas é definida nas configurações de agrupamento de colunas / tabelas / banco de dados. Você pode fazer a consulta em um agrupamento específico da seguinte maneira:

SELECT *
FROM trees
WHERE trees.`title` LIKE '%elm%' COLLATE utf8_general_ci

por exemplo.

(Substitua utf8_general_cipor qualquer agrupamento que achar útil). A _cisigla não faz distinção entre maiúsculas e minúsculas .


1
No MySQL 5.6, recebo o ERROR 1273 (HY000): agrupamento desconhecido: 'utf_general_ci' . Eu acho que esse agrupamento foi removido do MySQL? utf8_general_cifunciona bem, no entanto.
Mark Amery

1
Teve o mesmo problema. Você tem que corrigir o seu COLLATEou fazer um truque simples como este ( LOWER()ambas as cordas antes de comparação)
Menelau Kotsollaris

No MySQL 5.6+ ou MariaDB 10+, você só precisa fornecer as instruções COLLATE antes de sua condição. Portanto, isso funciona:SELECT * FROM products WHERE name COLLATE utf8_general_ci LIKE 'AB47TU';
stamster

41

Este é o exemplo de uma consulta LIKE simples:

SELECT * FROM <table> WHERE <key> LIKE '%<searchpattern>%'

Agora, sem distinção entre maiúsculas e minúsculas usando a função LOWER ():

SELECT * FROM <table> WHERE LOWER(<key>) LIKE LOWER('%<searchpattern>%')

3
Na verdade, esta é uma solução muito bom, especialmente quando você se depara com COLLATEquestões de formato
Menelau Kotsollaris

27

Basta usar:

"SELECT * FROM `trees` WHERE LOWER(trees.`title`) LIKE  '%elm%'";

Ou use

"SELECT * FROM `trees` WHERE LCASE(trees.`title`) LIKE  '%elm%'";

Ambas as funções funcionam da mesma maneira


15

Eu estou fazendo algo assim.

Obter os valores em minúsculas e MySQL faz o resto

    $string = $_GET['string'];
    mysqli_query($con,"SELECT *
                       FROM table_name
                       WHERE LOWER(column_name)
                       LIKE LOWER('%$string%')");

E para o MySQL PDO Alternative:

        $string = $_GET['string'];
        $q = "SELECT *
              FROM table_name
              WHERE LOWER(column_name)
              LIKE LOWER(?);";
        $query = $dbConnection->prepare($q);
        $query->bindValue(1, "%$string%", PDO::PARAM_STR);
        $query->execute();

6

Eu acho que essa consulta fará uma pesquisa sem distinção entre maiúsculas e minúsculas:

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';

1
Eu recebo erro de sintaxe no MySQL 5.5 ao usar ILIKE em minhas consultas
Aço Cérebro

18
Isso funciona apenas para PostgreSQL; não MySQL. postgresql.org/docs/current/static/functions-matching.html
Martin Tournoij

Como já foi observado, a pergunta era sobre o MySQL e a resposta é sobre o PostgreSQL e, com certeza, não funciona com o MySQL. Eu não baixo voto-lo, mas não posso deixar de me perguntar onde o up-votos vêm ...
silverdr


4

Você não precisa de ALTERnenhuma mesa. Basta usar as seguintes consultas, antes da SELECTconsulta real em que você deseja usar o curinga:

    set names `utf8`;
    SET COLLATION_CONNECTION=utf8_general_ci;
    SET CHARACTER_SET_CLIENT=utf8;
    SET CHARACTER_SET_RESULTS=utf8;

2
Este é um comentário muito subestimado. Ele aborda a questão de maneira mais geral. Eu acho que a sintaxe da alter table também é importante, pois a pergunta pode querer que a comparação seja limitada apenas a essa coluna.
22418 Brian Brianman

1

bem, no mysql 5.5, o operador like é insensível ... então, se seu vale é elm ou ELM ou Elm ou eLM ou qualquer outro e você usa como '% elm%', ele listará todos os valores correspondentes.

Não posso dizer sobre versões anteriores do mysql.

Se você for no Oracle, como trabalhar com distinção entre maiúsculas e minúsculas, se você digitar como '% elm%', será usado apenas isso e ignorará maiúsculas.

Estranho, mas é assim que é :)


Isso não é inteiramente verdade. Funciona dessa maneira somente se o agrupamento estiver definido como *_ci, que significa "insensitivo a maiúsculas e minúsculas". Como isso é o padrão para todos os conjuntos de caracteres suportados (problema show character set;para verificar isso) - a resposta é parcialmente verdadeira :-) Apenas o motivo está incorreto. Não é o operador que não diferencia maiúsculas de minúsculas, é o agrupamento padrão que é.
silverdr

sim, estou de acordo com você. Depende do caractere e, ainda assim, se você estiver em produção com o caractere * _ci, a única opção é usar a cláusula binário before where
user21546

1
SELECT name 
       FROM gallery 
       WHERE CONVERT(name USING utf8) LIKE _utf8 '%$q%' 
       GROUP BY name COLLATE utf8_general_ci LIMIT 5 

gallery é o nome da tabela, nome é a coluna na tabela,
user4189641 28/10

2
Por favor, adicione um pouco de explnataion de sua exibição código que ele faz e como ele ajuda - isso vai ajudar outros no futuro
Our Man in Bananas

0

Você deve configurar a codificação e ordenação adequadas para suas tabelas.

A codificação de tabela deve refletir a codificação de dados real. Qual é a sua codificação de dados?

Para ver a codificação da tabela, você pode executar uma consulta SHOW CREATE TABLE tablename


0

Quando quero desenvolver pesquisas de caso insensíveis, sempre converto todas as seqüências para minúsculas antes de fazer comparações


0

Você pode usar o seguinte método

 private function generateStringCondition($value = '',$field = '', $operator = '', $regex = '', $wildcardStart = '', $wildcardEnd = ''){
        if($value != ''){
            $where = " $field $regex '$wildcardStart".strtolower($value)."$wildcardEnd' ";

            $searchArray = explode(' ', $value);

            if(sizeof($searchArray) > 1){

                foreach ($searchArray as $key=>$value){
                    $where .="$operator $field $regex '$wildcardStart".strtolower($value)."$wildcardEnd'";
                }

            }

        }else{
            $where = '';
        }
        return $where;
    }

use este método como abaixo

   $where =  $this->generateStringCondition($yourSearchString,  'LOWER(columnName)','or', 'like',  '%', '%');
  $sql = "select * from table $where";

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.