Как выполнить поиск с учетом регистра в предложении WHERE?

21

Я хочу регистрозависимый поиск в запросе SQL. Но по умолчанию MySQL не рассматривает случай строк.

Любая идея о том, как сделать регистрозависимый поиск в запросе SQL?

Сомнат Мулук
источник

Ответы:

22

по умолчанию MySQL не учитывает регистр строк

Это не совсем так. Всякий раз, когда вы create databaseв MySQL, база данных / схема имеет набор символов и параметры сортировки. Каждый набор символов имеет сопоставление по умолчанию; смотрите здесь для получения дополнительной информации.

Сортировка по умолчанию для набора символов latin1, которая latin1_swedish_ciпроисходит без учета регистра.

Вы можете выбрать регистр с учетом регистра, например latin1_general_cs( грамматика MySQL ):

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

Это влияет на такие вещи, как группировка и равенство. Например,

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

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

В базе данных с учетом регистра мы получаем:

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   |
+----+-------+

Находясь в базе данных без учета регистра, мы получаем:

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   |
+----+-------+

Обратите внимание, что вы также можете изменить параметры сортировки в запросе . Например, в базе данных с учетом регистра я могу сделать

select * from casetable where thing collate latin1_swedish_ci = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+
Мэтт Фенвик
источник
13

Вы всегда должны указать своим вопросом, какую версию MySQL вы используете, потому что MySQL находится в постоянной разработке.

Хорошо, вернемся к вашему вопросу:

Строковые функции в MySQL всегда чувствителен к регистру, так что вы можете использовать любого из функций LOCATE, POSITIONили INSTR.

Например:

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

Сопоставление с шаблоном с регулярным выражением ( RLIKEили REGEXP) всегда чувствительно к регистру для всех версий MySQL, кроме самой новой версии 3.23.4.

Например:

SELECT phone FROM user WHERE user_name REGEXP 'term';

Как для обычного сравнения (=), так и для сопоставления с шаблоном SQL ( LIKE) поведение зависит от полей, которые включены:

а. CHAR, VARCHARи все варианты полей TEXT сравнивают без учета регистра.

б. CHAR BINARY, VARCHAR BINARY И все варианты BLOB полей делать сравнение чувствительно к регистру.

Если вы сравните поле из (a) с полем из (b), тогда сравнение будет чувствительным к регистру (выигрывает чувствительность к регистру). См. Главу «7.2.7 Строковые типы» Справочного руководства MySQL и найдите инструкции по сортировке и сравнению.

Начиная с версии V3.23.0 также возможно принудительное сравнение чувствительности к регистру с помощью оператора приведения BINARY, независимо от типов задействованных полей. См. Главу «7.3.7 Операторы приведения» Справочного руководства MySQL.

Так что вы также можете изменить тип user_name или с V3.23.x попробовать что-то вроде:

SELECT phone FROM user WHERE BINARY username LIKE '%term%';
Тургут
источник
1

В моей ситуации я использую Access 2010, но у меня была та же проблема, но решение другое: используйте StrComp()функцию и проверьте, что ее возвращение равно нулю.

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

Потому что StrComp()возвращает, -1если первый аргумент «меньше», 1если он «больше», и 0если он «равен», когда у StrComp()=0вас совпадение с учетом регистра.

Смотрите здесь , здесь или здесь .

Мартин Ф
источник
0

Это будет работать в MySQL независимо от набора символов. ВЫБЕРИТЕ «test» REGEXP BINARY «TEST» КАК РЕЗУЛЬТАТ; Установка BINARY заставляет двоичное сравнение.

user2288580
источник
-2

Попробуйте это для нечувствительного поиска, он отлично работает с отличной производительностью:

"SELECT phone FROM user WHERE lower(user_name) like ".srtlower($username);
Ганжи
источник