我有一个mysql数据库,需要对varchar列执行搜索。所有数据都用latin1编码。有时,这些列中有西方口音的字符(对我来说,几乎总是法语)。使用默认的排序规则(latin1_swedish_ci)对我来说一直都很好。但是现在我对一些包含umlauts的数据有了问题。如果我搜索"nusserhof“,我希望mysql返回"nüsserhof",但事实并非如此。将排序规则更改为latin1_german1_ci在最简单的意义上解决了问题,例如,此查询工作,返回包含单词“nüsserhof”的所有行:
select * from mytable where mycolumn like '%nusserhof%' collate latin1_german1_ci;select * from mytable where mycolumn like '%nusserhof%' order by mycolumn collate latin1_german1_ci;令人惊讶的是,无论是在这里还是通过谷歌,我都找不到这方面的任何信息。这是预期的行为吗?作为一项工作,我只是放弃订单,然后在PHP中对select进行排序。但看来我应该能让它起作用了。
发布于 2013-11-20 16:14:43
这是预期的行为吗?
是的,是这样的。
在瑞典语中,字形ü代表字母tyskt y(“德文Y"),因此在latin1_swedish_ci中,它是字母y的变体,而不是u。如果应用该排序规则搜索where mycolumn like '%nysserhof%',则将返回包含nüsserhof的记录。
在德语中,字形ü表示基字形的重音变体(特别是umlaut),因此在latin1_german1_ci下,它是字母u的预期变体。因此,在此排序规则下运行搜索时,您将获得所需的结果。
正是由于这种类型的本地差异,我们必须为数据选择适当的排序规则:在一般情况下,没有一个排序规则总是合适的。
应用ORDER BY时所观察到的问题源于对COLLATE关键字的误解:它不是SELECT命令的一部分(因此它指示MySQL对命令中的所有比较使用排序规则);相反,它是前一个字符串的一部分(因此它指示MySQL仅对前一个字符串使用显式排序规则)。
也就是说,在第一种情况下,显式latin1_german1_ci排序规则应用于矫顽力为0的'%nusserhof%'字符串文本;mycolumn排序规则(想必是latin1_swedish_ci)的矫顽力为2。由于前者的值较低,所以在计算表达式时使用它。
在第二个例子中,显式latin1_german1_ci排序规则应用于ORDER BY子句中的mycolumn:因此排序的结果将在'nu'和'nv'之间放置'nüsserhof',而不是在'ny'和'nz'之间。但是,显式排序规则不再适用于WHERE子句中的筛选器表达式,因此将应用列的默认排序规则。
如果mycolumn中的数据都是德语的,您可以简单地更改它的默认排序规则,不再担心在您的SQL命令中指定显式排序规则:
ALTER TABLE mytable MODIFY mycolumn <type> COLLATE latin1_german1_cihttps://stackoverflow.com/questions/20099847
复制相似问题