mysql整理latin1_german1_ci无法使用order by

时间:2013-11-20 15:21:01

标签: 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中选择后排序。但似乎我应该能够让它发挥作用。

1 个答案:

答案 0 :(得分:0)

  

这是预期的行为吗?

是的,是的。

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

在德语中,字形nüsserhof表示基本字形的重音变体(特别是变音符号),因此在latin1_german1_ci下,它是预期字母ü的变体。因此,在此归类下运行搜索时,您将获得所需的结果。

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

您在应用u时遇到的问题是由于对ORDER BY关键字的误解造成的:它是不是 COLLATE命令的一部分(如此它指示MySQL将该排序规则用于命令中的所有比较);相反,它是紧接在前的字符串的一部分(这样它指示MySQL仅对前一个字符串使用该显式排序规则)。

也就是说,在第一种情况下,显式SELECT归类应用于latin1_german1_ci字符串文字,coercibility为0; '%nusserhof%'(大概是mycolumn)的校对具有2的强制性。由于前者具有较低的值,因此在评估表达式时使用它。

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

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

mycolumn