Я хочу регистрозависимый поиск в запросе SQL. Но по умолчанию MySQL не рассматривает случай строк.
Любая идея о том, как сделать регистрозависимый поиск в запросе SQL?
источник
Я хочу регистрозависимый поиск в запросе SQL. Но по умолчанию MySQL не рассматривает случай строк.
Любая идея о том, как сделать регистрозависимый поиск в запросе SQL?
по умолчанию 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 |
+----+-------+
Вы всегда должны указать своим вопросом, какую версию 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%';
В моей ситуации я использую Access 2010, но у меня была та же проблема, но решение другое: используйте StrComp()
функцию и проверьте, что ее возвращение равно нулю.
StrComp( thing, 'abc', 0) = 0
Потому что StrComp()
возвращает, -1
если первый аргумент «меньше», 1
если он «больше», и 0
если он «равен», когда у StrComp()=0
вас совпадение с учетом регистра.
Это будет работать в MySQL независимо от набора символов. ВЫБЕРИТЕ «test» REGEXP BINARY «TEST» КАК РЕЗУЛЬТАТ; Установка BINARY заставляет двоичное сравнение.
Попробуйте это для нечувствительного поиска, он отлично работает с отличной производительностью:
"SELECT phone FROM user WHERE lower(user_name) like ".srtlower($username);