Como fazer uma pesquisa que diferencia maiúsculas de minúsculas na cláusula WHERE?

21

Quero pesquisa com distinção entre maiúsculas e minúsculas na consulta SQL. Mas, por padrão, o MySQL não considera o caso das strings.

Alguma idéia de como fazer uma pesquisa que diferencia maiúsculas de minúsculas na consulta SQL?

Somnath Muluk
fonte

Respostas:

22

por padrão, o MySQL não considera o caso das strings

Isso não é bem verdade. Sempre que você estiver create databaseno MySQL, o banco de dados / esquema possui um conjunto de caracteres e um agrupamento. Cada conjunto de caracteres possui um agrupamento padrão; veja aqui para mais informações.

O agrupamento padrão para o conjunto de caracteres latin1, que não latin1_swedish_cidiferencia maiúsculas de minúsculas.

Você pode escolher um agrupamento que diferencia maiúsculas de minúsculas, por exemplo latin1_general_cs( gramática MySQL ):

CREATE SCHEMA IF NOT EXISTS `myschema` 
DEFAULT CHARACTER SET latin1 
COLLATE latin1_general_cs ;

Isso afeta coisas como agrupamento e igualdade. Por exemplo,

create table casetable (
  id int primary key, 
  thing varchar(50)
);

select * from casetable;
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+

Em um banco de dados que diferencia maiúsculas de minúsculas, obtemos:

select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| ABC   |        1 |
| aBc   |        1 |
| abC   |        1 |
| abc   |        1 |
+-------+----------+

select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
+----+-------+

Enquanto em um banco de dados que não diferencia maiúsculas de minúsculas, obtemos:

select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| abc   |        4 |
+-------+----------+

select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+

Observe que você também pode alterar o agrupamento de dentro de uma consulta . Por exemplo, no banco de dados com distinção entre maiúsculas e minúsculas , eu posso fazer

select * from casetable where thing collate latin1_swedish_ci = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+
Matt Fenwick
fonte
13

Você sempre deve declarar com sua pergunta qual versão do MySQL você está usando, porque o MySQL está em constante desenvolvimento.

Ok, voltando à sua pergunta:

As funções de string no MySQL são sempre maiúsculas e minúsculas, então você poderia usar qualquer uma das funções LOCATE, POSITIONou INSTR.

Por exemplo:

SELECT phone FROM user WHERE POSITION('term' IN user_name)>0;

O padrão de correspondência com a expressão regular ( RLIKEou REGEXP) sempre diferencia maiúsculas de minúsculas para todas as versões do MySQL, exceto a mais recente 3.23.4.

Por exemplo:

SELECT phone FROM user WHERE user_name REGEXP 'term';

Para a comparação normal (=) e a correspondência de padrões SQL ( LIKE), o comportamento depende dos campos envolvidos:

uma. CHAR, VARCHAR, E todas as variantes de campos de texto se comparam caso insensível.

b. CHAR BINARY, VARCHAR BINARY e todas as variantes de campos BLOB comparam maiúsculas e minúsculas.

Se você comparar um campo de (a) com um campo de (b), a comparação fará distinção entre maiúsculas e minúsculas (a diferenciação de maiúsculas ganha). Veja o capítulo "7.2.7 Tipos de string" do Manual de Referência do MySQL e procure as instruções sobre classificação e comparações.

A partir da V3.23.0, também é possível forçar uma comparação na distinção entre maiúsculas e minúsculas com o operador de conversão BINARY, independentemente dos tipos de campos envolvidos. Veja o capítulo "7.3.7 Operadores de conversão" do Manual de Referência do MySQL.

Portanto, você também pode alterar o tipo de nome_do_usuário, ou com a V3.23.x tente algo como:

SELECT phone FROM user WHERE BINARY username LIKE '%term%';
Turgut
fonte
1

Na minha situação, estou usando o Access 2010, mas tive o mesmo problema, mas a solução é diferente: use a StrComp()função e teste seu retorno como zero.

StrComp( thing, 'abc', 0) = 0

Porque StrComp()retorna -1se o primeiro argumento for "menor", 1se for "maior" e 0se for "igual", quando StrComp()=0, você terá uma correspondência que diferencia maiúsculas de minúsculas.

Veja aqui , aqui ou aqui .

Martin F
fonte
0

Isso funcionará no MySQL, independentemente do conjunto de caracteres. SELECT 'test' REGEXP BINARY 'TEST' COMO RESULTADO; Colocar 'BINARY' força uma comparação binária.

user2288580
fonte
-2

Tente isso para pesquisas insensíveis, ele funciona bem com ótimo desempenho:

"SELECT phone FROM user WHERE lower(user_name) like ".srtlower($username);
ganji
fonte