mysql collat​​e latin1_german1_ci 不适用于 order by

标签 mysql

我有一个 mysql 数据库,我需要在其中对 varchar 列执行搜索。所有数据都以 latin1 编码。有时这些列中有西方重音字符(对我来说几乎总是法语。)使用默认排序规则 (latin1_swedish_ci) 对我来说一直很好。但是现在我遇到了一些包含变音符号的数据的问题。如果我搜索“nusserhof”,我希望 mysql 返回“nüsserhof”,但事实并非如此。将排序规则更改为 latin1_german1_ci 可以从最简单的意义上解决问题,例如此查询有效,返回包含单词“nüsserhof”的所有行:

select * from mytable where mycolumn like '%nusserhof%' collate latin1_german1_ci;

但是如果我添加一个 order by 子句,它就不再有效了。这不会返回任何包含单词“nüsserhof”的行:

select * from mytable where mycolumn like '%nusserhof%' order by mycolumn collate latin1_german1_ci;

令人惊讶的是,我在这里或通过谷歌找不到任何关于此的信息。这是预期的行为吗?作为解决方法,我只是放弃顺序,并在 PHP 中选择之后进行排序。但似乎我应该能够让它工作。

最佳答案

Is this expected behavior?

是的,是的。

在瑞典语中,字形 ü 代表字母 tyskt y(“德语 Y”),因此位于 latin1_swedish_ci 之下它是字母 y 而不是 u 的变体。如果应用该排序规则,您要搜索 where mycolumn like '%nysserhof%',将返回包含 nüsserhof 的记录。

在德语中,字形 ü 表示基本字形的重音变体(特别是元音变音),因此在 latin1_german1_ci 之下。正如预期的那样,它是字母 u 的变体。因此,在此排序规则下运行搜索时,您会获得所需的结果。

正是由于这种局部差异,我们必须为我们的数据选择合适的排序规则:在一般情况下,没有一种排序规则总是合适的。

您在应用 ORDER BY 时观察到的问题源于对 COLLATE 关键字的误解:它不是 的一部分>SELECT 命令(这样它指示 MySQL 使用该排序规则进行命令中的所有比较);相反,它是紧接在前的字符串的一部分(这样它指示 MySQL 仅对紧接在前的字符串使用该显式排序规则)。

也就是说,在您的第一种情况下,显式 latin1_german1_ci 归类应用于带有 coercibility'%nusserhof%' 字符串文字的 0; mycolumn 的排序规则(大概是 latin1_swedish_ci)的强制性为 2。由于前者的值较低,因此在计算表达式时使用它。

在第二种情况下,显式 latin1_german1_ci 排序规则应用于 ORDER BY 子句中的 mycolumn:因此排序结果将放置 'nüsserhof''nu''nv' 之间,而不是在 'ny''nz 之间'。但是,显式排序规则不再适用于 WHERE 子句中的过滤器表达式,因此将应用该列的默认排序规则。

如果 mycolumn 中的数据全部为德语,您只需更改其默认排序规则,而不必再担心在 SQL 命令中指定显式排序规则:

ALTER TABLE mytable MODIFY mycolumn <type> COLLATE latin1_german1_ci

关于mysql collat​​e latin1_german1_ci 不适用于 order by,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20099847/

相关文章:

mysql - 删除查询的SQL

PHP/MySQL : Storing and retrieving UUIDS

php - 在html中使用php代码动态加载下拉列表

php - 将元素同步到 Laravel 上的子元素

php - echo 当前行数

mysql - mysql essential 和 community 版本的区别

php - APC缓存一致性问题

使用组合 xy 或 yx 的 MySQL 更新查询

mysql - SQL查询不知道变量

php - mysql中数组的数据类型