如何在MySQL上进行SQL区分大小写的字符串比较?

时间:2011-04-12 00:36:17

标签: mysql sql interop case-sensitive string-comparison

我有一个函数,返回带有大小写混合的五个字符。如果我对这个字符串进行查询,它将返回值而不管大小写。

如何使MySQL字符串查询区分大小写?

11 个答案:

答案 0 :(得分:637)

好消息是,如果您需要进行区分大小写的查询,则很容易做到:

SELECT *  FROM `table` WHERE BINARY `column` = 'value'

答案 1 :(得分:133)

http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

  

默认字符集和排序规则是latin1和latin1_swedish_ci,因此非二进制字符串比较默认情况下不区分大小写。这意味着如果使用col_name LIKE'a%'进行搜索,则会获得以A或a开头的所有列值。要使此搜索区分大小写,请确保其中一个操作数具有区分大小写或二进制排序规则。例如,如果要比较具有latin1字符集的列和字符串,则可以使用COLLATE运算符使任一操作数具有latin1_general_cs或latin1_bin排序规则:

col_name COLLATE latin1_general_cs LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_general_cs
col_name COLLATE latin1_bin LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_bin
  

如果希望始终以区分大小写的方式处理列,请使用区分大小写或二进制排序规则来声明它。

答案 2 :(得分:35)

您可能希望使用LIKE或LIKE BINARY

,而不是使用=运算符
// this returns 1 (true)
select 'A' like 'a'

// this returns 0 (false)
select 'A' like binary 'a'


select * from user where username like binary 'a'

在条件

中需要'a'而不是'A'

答案 3 :(得分:30)

Craig White发布的答案,性能损失很大

SELECT *  FROM `table` WHERE BINARY `column` = 'value'

因为它不使用索引。因此,您需要更改表格排序规则,如此处提及https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html

OR

最容易修复,你应该使用价值的BINARY。

SELECT *  FROM `table` WHERE `column` = BINARY 'value'

EG。

mysql> EXPLAIN SELECT * FROM temp1 WHERE BINARY col1 = "ABC" AND col2 = "DEF" ;
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | temp1  | ALL  | NULL          | NULL | NULL    | NULL | 190543 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+

VS

mysql> EXPLAIN SELECT * FROM temp1 WHERE col1 = BINARY "ABC" AND col2 = "DEF" ;
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
| id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows | Extra                              |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
|  1 | SIMPLE      | temp1 | range | col1_2e9e898e | col1_2e9e898e | 93      | NULL |    2 | Using index condition; Using where |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
enter code here

1行(0.00秒)

答案 4 :(得分:13)

要在使用BINARY之前使用索引,如果你有大表,你可以这样做。

SELECT
   *
FROM
   (SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
   BINARY `column` = 'value'

子查询会产生一个非常小的不区分大小写的子集,然后您可以选择唯一区分大小写的匹配。

答案 5 :(得分:7)

以下是适用于等于或高于5.5的MySQL版本。

添加到/etc/mysql/my.cnf

  [mysqld]
  ...
  character-set-server=utf8
  collation-server=utf8_bin
  ...

我尝试的所有其他排序规则似乎都不区分大小写,只有“utf8_bin”有效。

不要忘记在此之后重新启动mysql:

   sudo service mysql restart

根据http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html,还有一个“latin1_bin”。

mysql启动不接受“utf8_general_cs”。 (我将“_cs”视为“区分大小写” - ???)。

答案 6 :(得分:5)

您可以像这样使用BINARY区分大小写

select * from tb_app where BINARY android_package='com.Mtime';

不幸的是,这个sql不能使用索引,依赖于该索引的查询会遭受性能损失

mysql> explain select * from tb_app where BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | tb_app | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1590351 |   100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+

幸运的是,我有一些技巧可以解决这个问题

mysql> explain select * from tb_app where android_package='com.Mtime' and BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table  | partitions | type | possible_keys             | key                       | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_app | NULL       | ref  | idx_android_pkg           | idx_android_pkg           | 771     | const |    1 |   100.00 | Using index condition |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+  

答案 7 :(得分:1)

出色!

我与您分享来自比较密码的函数的代码:

SET pSignal =
(SELECT DECODE(r.usignal,'YOURSTRINGKEY') FROM rsw_uds r WHERE r.uname =
in_usdname AND r.uvige = 1);

SET pSuccess =(SELECT in_usdsignal LIKE BINARY pSignal);

IF pSuccess = 1 THEN
      /*Your code if match*/
ELSE
      /*Your code if don't match*/

END IF;

答案 8 :(得分:1)

无需更改数据库级别的任何内容,只需在SQL查询中进行更改即可。

示例 -

func isStoreKitAvailable() -> Bool { for frameWorkName in Bundle.allFrameworks { if ((frameWorkName.classNamed("SKStoreProductViewController")) != nil) { return true; } } return false; }

二进制关键字会区分大小写。

答案 9 :(得分:1)

执行区分大小写的字符串比较而不更改要查询的列的排序规则的最正确方法是为要比较的列的值显式指定一个字符集和排序规则。

select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;

为什么不使用binary

不建议使用binary运算符,因为它会比较编码字符串的实际字节。如果比较使用不同字符集编码的两个字符串的实际字节,则两个应该被视为相同的字符串可能不相等。例如,如果您有一列使用latin1字符集,并且服务器/会话字符集是utf8mb4,则当您将该列与包含重音符号的字符串(例如“café”)进行比较时,将不匹配包含相同字符串的行!这是因为在latin1中é被编码为字节0xE9,而在utf8中则被编码为两个字节:0xC3A9

为什么同时使用convertcollate

排序规则必须与字符集匹配。因此,如果服务器或会话设置为使用latin1字符集,则必须使用collate latin1_bin,但如果字符集是utf8mb4,则必须使用collate utf8mb4_bin。因此,最可靠的解决方案是始终将值转换为最灵活的字符集,并对该字符集使用二进制排序规则。

为什么将convertcollate应用于值而不是列?

在进行比较之前,对列应用任何转换功能时,如果该列存在索引,则查询引擎将无法使用该索引,这可能会大大降低查询速度。因此,最好总是尽可能地转换值。当在两个字符串值之间执行比较,并且其中一个具有明确指定的排序规则时,查询引擎将使用该明确排序规则,无论将其应用于哪个值。

口音敏感度

请务必注意,MySql不仅对使用_ci归类(通常是默认设置)的列不区分大小写,而且对 accent 不区分大小写。这意味着'é' = 'e'。使用二进制排序规则(或binary运算符)将使字符串比较区分重音和区分大小写。

什么是utf8mb4

MySql中的utf8字符集是deprecated in recent versionsutf8mb3的别名,因为它不支持4字节字符(这对于编码像字符串很重要)。如果您希望将UTF8 character encoding与MySql一起使用,则应该使用utf8mb4字符集。

答案 10 :(得分:0)

默认情况下,mysql不区分大小写,请尝试将语言排序规则更改为latin1_general_cs