MySQL不区分大小写的选择


242

谁能告诉我SELECT默认情况下MySQL 查询是否区分大小写?如果没有,我将要发送什么查询,以便执行以下操作:

SELECT * FROM `table` WHERE `Value` = "iaresavage"

实际上,的真正价值ValueIAreSavage


44
最终,它取决于归档排序规则-是'_ci'(不区分大小写)还是'_cs'(区分大小写)
Jovan Perovic

15
这是一个措辞不佳的问题;)。一半的答案向您展示如何进行不区分大小写的比较,一半的答案旨在区分大小写。而且只有1告诉您默认值实际上不区分大小写。:)值得注意的是,即使您进行比较,例如'value' in ('val1', 'val2', 'val3')
SaltyNuts 2013年

5
@SaltyNuts的男人,在7年后阅读了这个问题,并意识到我有多少菜鸟让我感到尴尬!我本来可以阅读文档,而答案就像关于SELECT语句的第一句话一样……
NoodleOfDeath

除了@JovanPerovic所说的以外,utf8_bin还使其区分大小写。不确定当时是否存在
Chiwda

Answers:


494

除非您进行二进制比较,否则它们不区分大小写


3
我大体上同意Tim的评论,我不认为到处对您的值执行“ lower()”是处理它的最佳方法,这似乎是一种解决方法。但我承认有时这很有意义并且更容易。(Colin确实提到整理更好)。由于某些列值不区分大小写,我们将历史数据移入了mysql表,这破坏了传统逻辑。我们需要知道“ GE1234”和“ ge1234”之间的区别,它们需要唯一并保持这种状态。我们改用这种方式在create table语句中设置列:varchar(20)CHARACTER SET utf8 COLLATE utf8_bin
gregthegeek 2014年

19
我不知道为什么有这么多人投票赞成。此处清楚地指出dev.mysql.com/doc/refman/5.0/en/case-sensitiveivity.html “ ...这意味着对于字母字符,比较将区分大小写。” 因此,如果我寻找“ DickSavagewood”,它将不会拾取“ dicksavagewood”。用LOWER()进行同样的操作会把它捡起来。因此,我对这个问题的回答是:在您的特定情况下,SELECT确实区分大小写。
Luftwaffle 2014年

10
@ user1961753:重新阅读:“对于二进制字符串(varbinary,blob)...将区分大小写”。
Marc B

1
@MarcB此链接已断开。你能修好吗?:)
Phiter '16

5
如Jovan所说,这取决于排序规则,所以这个答案几乎是错误的。
phil294

117

您可以小写值和传递的参数:

SELECT * FROM `table` WHERE LOWER(`Value`) = LOWER("IAreSavage")

另一种(更好)的方法是使用文档中COLLATE所述的运算符


21
那么,SELECT使用该语句将如何显示COLLATE
是Barry,

11
它在上面提到的文档页面上说:“默认情况下,非二进制字符串比较不区分大小写”。
质疑阿龙森

9
多少人对这个答案表示恐惧。正如@Marc上文所述,比较不区分大小写的。您需要了解排序规则和索引并进行适当的配置-使用诸如此类的字符串转换LOWER()或任意COLLATE子句可以完全绕过索引,并且随着时间的流逝,随着表的增长,这可能会对性能产生巨大影响。这些可能是您要查找的用户名?使用不区分大小写的排序规则,并向该列添加唯一索引。使用EXPLAIN以确认正在使用的索引。
mindplay.dk

1
我要说的与mindplay.dk相同... upper()和Lower()绕过索引,直接影响大型数据库表的性能。
GTodorov '18

我同意mindplay.dk和GTodorov的意见。在where子句的目标列上使用某些方法时要小心。列的索引可能没有用。使用EXPLAIN!
traeper,2018年

51

使用二进制

这是一个简单的选择

SELECT * FROM myTable WHERE 'something' = 'Something'

= 1

这是带有二进制的选择

SELECT * FROM myTable WHERE BINARY 'something' = 'Something'

要么

SELECT * FROM myTable WHERE 'something' = BINARY 'Something'

= 0


3
什么时候仅在=(SELECT * FROM myTable WHERE BINARY'something'='Something')的一侧使用BINARY才有意义?
吉米

@Jimmy你到底是什么意思?该代码有效。当比较中的一侧转换为二进制时,比较将完成二进制。
2014年

@Jori哦,我想我读错了-我认为两个示例之一在等式的两边都有BINARY。
吉米

我刚刚投了赞成票,因为这确实是正确的答案。根据MySQL网站上的文档,他们说使用BINARY命令比尝试将单词/请求类型转换为特定语言要好,因为BINARY命令说要保留所有内容并准确使用它被呈现。因此,当我随便寻找一个答案时,这里的两个答案将我带到了MySQL网站并查看了他们的文档资料。使用BINARY更好。翻译可能会导致其他问题。
马克·曼宁

43

比较是不区分大小写当列使用其结尾的对照_ci(如缺省 latin1_general_ci排序规则),并且它们是大小写敏感的,当列使用的对照,其端部与_cs_bin(如utf8_unicode_csutf8_bin归类)。

检查整理

您可以使用以下方法检查服务器数据库连接的排序规则:

mysql> show variables like '%collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

您可以使用以下方法检查排序规则:

mysql> SELECT table_schema, table_name, table_collation 
       FROM information_schema.tables WHERE table_name = `mytable`;
+----------------------+------------+-------------------+
| table_schema         | table_name | table_collation   |
+----------------------+------------+-------------------+
| myschema             | mytable    | latin1_swedish_ci |

变更归类

您可以将数据库,表或列的排序规则更改为区分大小写的方式,如下所示:

-- Change database collation
ALTER DATABASE `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

-- or change table collation
ALTER TABLE `table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

-- or change column collation
ALTER TABLE `table` CHANGE `Value` 
    `Value` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;

现在,您的比较应该区分大小写。


25

WHERE短语中的字符串比较不区分大小写。您可以尝试比较使用

WHERE `colname` = 'keyword'

要么

WHERE `colname` = 'KeyWord'

你会得到相同的结果。这是MySQL的默认行为。

如果您希望比较区分大小写,则可以这样添加COLLATE

WHERE `colname` COLLATE latin1_general_cs = 'KeyWord'

该SQL将在此结果中给出不同的结果:WHERE colname COLLATE latin1_general_cs ='keyword'

latin1_general_cs 在大多数数据库中是常见或默认排序规则。



9

默认值是不区分大小写的,但是接下来要看的最重要的事情是表是如何创建的,因为在创建表时可以指定区分大小写。

下面的脚本创建一个表。请注意,底部显示“ COLLATE latin1_general_cs”。最后的cs表示区分大小写。如果希望表不区分大小写,则可以省略该部分,或者使用“ COLLATE latin1_general_ci”。

   CREATE Table PEOPLE (

       USER_ID  INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

       FIRST_NAME  VARCHAR(50) NOT NULL,
       LAST_NAME  VARCHAR(50) NOT NULL,

       PRIMARY KEY (USER_ID)

   )

   ENGINE=MyISAM DEFAULT CHARACTER SET latin1
    COLLATE latin1_general_cs AUTO_INCREMENT=0;

如果您的项目可以创建自己的表,则在创建表时指定区分大小写的首选项是有意义的。




2

还要注意,在Linux上,表名区分大小写,除非将lower_case_table_nameconfig伪指令设置为1。这是因为表由Linux区分大小写的文件表示。

尤其要注意在不区分大小写的Windows上进行的开发,并将其部署到实际的生产环境中。例如:

"SELECT * from mytable" 

除非已设置上述指令,否则针对表myTable的表将在Windows中成功但在Linux中失败。

此处参考:http : //dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitiveivity.html


1
+1-写不区分大小写的查询然后在Linuxes上失败的情况在我们的项目中发生了很多
Vic

@Vic我的项目遇到同样的问题。您能告诉我您如何解决它吗?
卡姆兰·艾哈迈德

@KamranAhmed,您需要使用表名的大小写与创建脚本中显示的完全一样
Vic

@Vic将是最后的手段,因为我不得不修改大量的查询。我在想,是否有任何简单的方法可以做到这一点。不过谢谢!
卡姆兰·艾哈迈德

@KamranAhmed,尝试lower_case_table_name按照我们在以下评论中给出的答案中指定的进行更改
Vic

1

当前接受的解决方案大部分是正确的。

如果您使用非二进制字符串(CHAR,VARCHAR,TEXT),则根据默认排序规则,比较不区分大小写

如果您使用二进制字符串(BINARY,VARBINARY,BLOB),则比较区分大小写,因此您需要LOWER按照其他答案中的描述使用。

如果您没有使用默认排序规则,而是使用非二进制字符串,则区分大小写取决于所选的排序规则。

来源:https : //dev.mysql.com/doc/refman/8.0/en/case-sensitiveivity.html。仔细阅读。其他一些人则误以为比较必须区分大小写或不区分大小写。不是这种情况。


0

你可以试试。希望它会有用。

SELECT * FROM `table` WHERE `Value` COLLATE latin1_general_cs = "IAreSavage"

0

设置了二进制标志的字符串字段将始终区分大小写。如果需要对非二进制文本字段进行区分大小写的搜索,请使用此方法:SELECT'test'REGEXP BINARY'TEST'AS RESULT;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.