从mySQL数据库中按正确顺序排序条目 - 变音符号在字符“Z”之后

时间:2013-07-12 10:31:20

标签: php mysql sorting typo3 iso-8859-1

从mySQL数据库中排序我的值时,我得到以下错误的排序顺序:

SELECT * FROM tt_news WHERE pid=19 AND deleted=0 AND hidden=0 order by title ASC

A  
B  
C  
...  
Ä  
Ö

我可以针对此排序问题做些什么? Ä应该在A之间或之后,等等。

MySQL服务器版本:5.0.51a,支持UTF-8

我发现这与数据库的整理有关(参见德语链接:http://mysql-faq.sourceforge.net/tables3.html)。

脚本嵌入到TYPO3中,setDBinit设置为SET NAMES utf8forceCharset设置为UTF-8。因此,UTF-8数据应存储在ISO-8859-1(Latin 1)中。

该列的类型为text,排序规则为latin1_swedish_ci。当我在phpMyAdmin中输入SHOW VARIABLES LIKE 'collation%'时,我得到了

collation_connection    utf8_general_ci
collation_database  latin1_swedish_ci
collation_server    latin1_swedish_ci

SHOW VARIABLES LIKE '%CHARACTER_SET%';在phpMyAdmin

中提供给我
character_set_client    utf8
character_set_connection    utf8
character_set_database  latin1
character_set_filesystem    binary
character_set_results   utf8
character_set_server    latin1
character_set_system    utf8
character_sets_dir  /usr/share/mysql/charsets/

尝试1号:

我尝试在我的脚本中使用SET NAMES utf8;,但这并未改变某些内容。

尝试2号:

我想在PHP中进行排序(根据此SOQ:How to sort an array of associative arrays by value of a given key in PHP?),但这并没有改变排序。

$title=array();
foreach ($result as $key => $row) {
    $title[$key]  = $row['title'];
}
array_multisort($title, SORT_ASC, $result);

尝试3号:

我使用了mySQL语句(取自http://blog.mixable.de/mysql-order-by-und-deutsche-umlaute/):

SELECT * FROM tt_news WHERE pid=19 AND deleted=0 AND hidden=0 order by title COLLATE latin1_swedish_ci;

排序没有变化。使用utf-8会导致错误(不允许整理)。

尝试4号:

SELECT *, REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE(REPLACE(title, 'Ä', 'A'), 'Ö', 'O'), 'Ü', 'U'), 'ä', 'a'), 'ö', 'o'), 'ü','u'), 'ß', 's') AS sortiert FROM tt_news WHERE pid=19 AND deleted=0 AND hidden=0 ORDER BY sortiert

来源:http://www.php-faq.de/q-mysql-umlaute-sortieren.html

在phpMyAdmin中工作,但不在我的脚本中。我收到以下错误:Illegal mix of collations (latin1_swedish_ci,IMPLICIT), (utf8_general_ci,COERCIBLE), (utf8_general_ci,COERCIBLE) for operation 'replace'

我可以在不改变字符集或整理的情况下在PHP中进行正确的排序吗?

4 个答案:

答案 0 :(得分:2)

您看到的顺序是正确的瑞典规则:Å,Ä和Ö是Z之后字母表中的最后三个字母。如果您不喜欢它,请更改列整理等等其他

alter table tt_news modify title text collate latin1_general_ci;

general变体会将字符的所有重音变体视为不同,但在排序时将它们组合在一起;例如,AZ出现在ÄA之前。如果您需要除瑞典语以外的一些国家标准,请参阅MySQL支持的列表:http://dev.mysql.com/doc/refman/5.6/en/charset-we-sets.html

如果无法更改数据库中的列排序规则,则可以告诉MySQL仅使用特定的排序规则来排序查询。例如:

.... order by title collate latin1_general_ci

答案 1 :(得分:0)

纯PHP解决方案:

function sortWUmlauts($s1, $s2)
{
    $s1 = $s1['title'];
    $s2 = $s2['title'];
    $search = array('Ä','Ö','Ü','ß');
    $replace = array('A','O','U','s');

    return strcasecmp(
       str_ireplace($search, $replace, $s1),
       str_ireplace($search, $replace, $s2)
    );
}

// call
uasort($result, 'sortWUmlauts');

取自http://at2.php.net/manual/en/function.uasort.php#99017

一个很好的补充是有一个变量,它保存关联数组的搜索关键字(直接在uasort调用中嵌入函数)。

答案 2 :(得分:0)

使用"按标题排序latin1_german1_ci"为了

Ä = A
Ö = O
Ü = U
ß = s

使用"按标题排序latin1_german2_ci"对

Ä = AE
Ö = OE
Ü = UE
ß = ss

排序更多http://dev.mysql.com/doc/refman/5.6/en/charset-we-sets.html

答案 3 :(得分:0)

您不必修改数据库来执行此操作(当然,除非您想要)。也许你想根据不同的语言对不同的列进行排序?

只需在查询中指定其他排序规则,例如:

SELECT * FROM tt_news WHERE pid=19 ORDER BY title COLLATE "utf8_german2_ci" ASC

请注意,如果您的表格尚未处于utf8排序规则(可能是latin1排序规则),那么您需要使用latin1排序规则进行排序。在这种情况下,您可以在上面的查询中使用latin1_german2_ci代替utf8_german2_ci

MySQL reference docs here中提供了归类列表以及对其用途的有用讨论。