【问题标题】:MySQL: is a SELECT statement case sensitive?MySQL:SELECT 语句是否区分大小写?
【发布时间】:2023-03-17 10:23:01
【问题描述】:

谁能告诉我 MySQL SELECT 查询是否默认区分大小写或不区分大小写?如果没有,我必须发送什么查询才能执行以下操作:

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

实际上,Value 的实际值为IAreSavage

【问题讨论】:

  • 最终取决于归档排序规则 - 如果它是“_ci”(不区分大小写)或“_cs”(区分大小写)
  • 这是一个措辞不当的问题;)。一半的答案向您展示如何进行不区分大小写的比较,一半的目标是区分大小写。只有 1 告诉您默认值实际上是不区分大小写的。 :) 值得注意的是,即使您进行'value' in ('val1', 'val2', 'val3') 之类的比较,也不区分大小写仍然有效
  • @SaltyNuts 伙计,7 年后读了这个问题,意识到我是多么的菜鸟是多么尴尬!我本可以只阅读文档,答案就像关于 SELECT 语句的第一句话......
  • 补充@JovanPerovic 所说的内容,utf8_bin 还使其区分大小写。不知道当时是否存在

标签: mysql select


【解决方案1】:

它们不区分大小写,除非您使用binary comparison

【讨论】:

  • 我基本上同意蒂姆的评论,我不认为在任何地方对你的价值观做一个“lower()”是处理它的最好方法,似乎是一种解决方法。但我承认它有时是有道理的,而且更容易。 (Colin 确实提到了整理更好)我们将历史数据移到了 mysql 表中,这破坏了旧逻辑,因为某些列值不区分大小写。我们需要知道“GE1234”和“ge1234”之间的区别,它们需要是唯一的并以这种方式保持记录。我们以这种方式在 create table 语句中设置列:varchar(20) CHARACTER SET utf8 COLLATE utf8_bin
  • 我不知道为什么这么多人投票赞成。它在这里明确指出dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html“......这意味着对于字母字符,比较将区分大小写。”因此,如果我寻找“DickSavagewood”,它不会选择“dickSavagewood”。用 LOWER() 做同样的事情会捡起它。所以我对这个问题的回答:在您的特定情况下,SELECT 确实区分大小写。
  • @user1961753:再读一遍:“对于二进制字符串(varbinary,blob)......将区分大小写”。
  • @MarcB 此链接现已损坏。你能修好吗? :)
  • 正如 Jovan 所说,这取决于排序规则,所以这个答案是非常错误的。
【解决方案2】:

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

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

另一种(更好的)方法是使用COLLATE 运算符,如in the documentation 所述

【讨论】:

  • 如果使用COLLATE,这个SELECT 语句会怎样?
  • 上面提到的文档页面上说“默认情况下,非二进制字符串比较不区分大小写”。
  • 有点吓人,有多少人支持这个答案。正如@Marc 上面解释的那样,比较 不区分大小写。您需要了解排序规则和索引并正确配置它们 - 使用 LOWER() 或任意 COLLATE 子句之类的字符串转换可以完全绕过索引,并且随着时间的推移,随着表的增长,这可能会对性能产生巨大影响。可能这些是您正在查找的用户名?使用不区分大小写的排序规则并向列添加唯一索引。使用EXPLAIN 确认索引正在被使用。
  • 我正要说和mindplay.dk一样……upper()和lower()绕过索引,直接影响大型数据库表的性能。
  • 我同意 mindplay.dk 和 GTodorov 的观点。在 where 子句中的目标列上使用某些方法时要小心。列的索引可以是无用的。使用解释!
【解决方案3】:

当列使用以_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;

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

【讨论】:

  • 这是答案,而其他人(即使有更多的赞成票)是解决方法。
【解决方案4】:

使用二进制

这是一个简单的选择

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

= 1

这是一个带二进制的选择

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

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

= 0

【讨论】:

  • 什么时候只在 = (SELECT * FROM myTable WHERE BINARY 'something' = 'Something') 的一侧使用 BINARY 才有意义?
  • @Jimmy 你到底是什么意思?该代码有效。当比较中的一侧转换为二进制时,比较是二进制完成的。
  • @Jori 哦,我想我看错了——我认为这两个例子中的一个在等式的两边都有 BINARY。
  • 我刚刚投了这个票,因为这确实是正确的答案。根据 MySQL 网站上的文档,他们说使用 BINARY 命令比尝试将您的单词/请求类型转换为特定语言更好,因为 BINARY 命令说要保持原样并完全按照它被提出。因此,当我来寻找答案时——这里的两个答案将我带到了 MySQL 网站并查看了他们的文档。使用 BINARY 更好。翻译可能会导致其他问题。
【解决方案5】:

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 在大多数数据库中是常见的或默认的排序规则。

【讨论】:

    【解决方案6】:

    您选择的排序规则设置您是否区分大小写。

    【讨论】:

      【解决方案7】:

      默认不区分大小写,但是 下一个最重要的事情 你应该看看表是如何创建的 首先,因为您可以指定大小写 创建表时的敏感度。

      下面的脚本创建一个表。 请注意底部显示“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;
      

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

      【讨论】:

        【解决方案8】:

        Marc B 的回答大部分是正确的。

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

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

        如果您未使用默认排序规则并且使用的是非二进制字符串,则区分大小写由所选排序规则决定。

        来源:https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html。仔细阅读。有些人误以为比较必然区分大小写或不区分大小写。事实并非如此。

        【讨论】:

          【解决方案9】:

          【讨论】:

          • 取决于您的数据库,正如此处其他地方所指出的,它们可以在 mysql 上。
          【解决方案10】:

          尝试:

          order by lower(column_name) asc;
          

          【讨论】:

            【解决方案11】:

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

            特别要注意在不区分大小写的 Windows 上进行开发并在其所在位置部署到生产环境。例如:

            "SELECT * from mytable" 
            

            除非设置了上述指令,否则 myTable 在 Windows 中会成功,但在 Linux 中会失败。

            参考这里:http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html

            【讨论】:

            • +1 - 编写不区分大小写的查询然后在 Linux 上失败的场景在我们的项目中发生了很多
            • @Vic 我的项目也有同样的问题。你能告诉我你是怎么解决的吗?
            • @KamranAhmed,您需要完全按照创建脚本中的表名使用大小写
            • @Vic 那将是最后的手段,因为我必须修改大量的查询。我想知道是否有任何简单的方法可以做到这一点。不过谢谢!
            • @KamranAhmed,尝试更改lower_case_table_name,正如我们在下面评论的答案中指定的那样
            【解决方案12】:

            你可以试试。 希望对你有用。

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

            【讨论】:

              【解决方案13】:

              设置了二进制标志的字符串字段将始终区分大小写。 如果您需要对非二进制文本字段进行区分大小写的搜索,请使用以下命令: 选择“测试”正则表达式二进制“测试”作为结果;

              【讨论】:

                猜你喜欢
                • 2010-09-14
                • 2014-09-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-11-16
                相关资源
                最近更新 更多