繁体   English   中英

如何对 SQL 查询进行排序,但将某些 UTF-8 字符排序为正常等效字符? (例如É被视为E等)

[英]How can I sort an SQL query but have certain UTF-8 characters be ordered as their normal equivalent? (e.g. É be regarded as E etc)

我在 mySQL 数据库中有一个字符名称表。

我正在尝试查询表格并按名称按字母顺序对它们进行排序。

一些字符的名称如“The Dagda”和“The”需要被忽略,所以我尝试使用:

select character_id, name from characters where is_del=0 order by trim('The ' from name)

这似乎工作......

其他一些字符的名称中包含 UTF-8 字符,例如“Ériu”

但是,现在当我的表被返回时,我会在“A”和“B”之间列出这些“É”条目。

IE:

Aengus Amergin Ériu Balor Banba 等

保留这些 UTF 字符在前端至关重要。

有谁知道一种方法,我可以将这些“É”字符和类似字符表示为“E”以进行排序,但仍会在数据集中呈现它们的实际情况?

在问这个问题之前我在想这可能是不可能的,但我希望这里的某个人之前可能遇到过类似的问题并且可能有解决方法。

提前致谢。

编辑:将 UTF-16 更改为 UTF-8(我的错)

编辑@Rick James:

我无法在评论中以可读的方式格式化它,但查询的十六进制如下:

姓名 | 十六进制(名称)

安格斯·格 | 41656E67757320C383E2809C67
阿美金 | 416D657267696E
らriu | C383E280B0726975
巴洛尔 | 42616C6F72
板坝 | 42616E6261

向下的第 3 项是 Ériu - 我不确定它们为什么会像上面那样呈现,但这是当我运行查询select character_id, name, hex(name) from characters order by trim('The ' from name)

第一个角色的全名应该是 Aengus Óg (我假设这又归结为字符集或排序规则,但我不确定是否为我在这里的无知而道歉)

“双重编码”似乎是问题所在。 我在UTF-8 字符的麻烦中对此进行了一些讨论; 我看到的不是我存储的

应该`

41 65 6E 67 75 73 20 C383 E2809C 67

Óg是 UTF-8 中的十六进制C393 67

Latin1 hex C3 93 67Óg

重复得到C383 E2809C 67

CONVERT(BINARY(CONVERT('Aengus Óg' USING latin1))
               USING utf8mb4) --> 'Aengus Óg'

这似乎是“双重编码”:

CONVERT(BINARY(CONVERT(CONVERT(UNHEX('C383E280B0726975') USING utf8mb4) USING latin1)) USING utf8mb4) --> 'Ériu'

Ériu作为中间步骤。 这解释了为什么它与 A 排序。

这是一个常见的问题。 它经常被忽视,因为浏览器“修复”了混乱。

对表进行 SELECT 试验。 如果第一个适合您,那么它就是 Mojibake。

SELECT CONVERT(BINARY(CONVERT(my_column USING latin1))
               USING utf8mb4)
    FROM ... WHERE ...;

阅读其他问答,了解哪些步骤出错导致问题。 它可能涉及将 UTF-8 字符存储在声明为latin1的列中。

ALTER TABLE ... CONVERT TO ...假定数据已正确存储。 但事实并非如此。 现在您已在列上正确设置了CHARACTER SET ,但其中的数据已被 Mojibaked。 所以,它需要类似的东西

UPDATE tbl  SET
    col1 = CONVERT(BINARY(CONVERT(col1 USING latin1))
           USING utf8mb4),
    col2 = CONVERT(BINARY(CONVERT(col2 USING latin1))
           USING utf8mb4),
    ...
    ;

有关修复的更多信息:http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases

回滚? 如果您更愿意回滚到 CONVERT TO 之前,那么忽略我之前所说的大部分内容,那么您需要在回滚之后进行 2 步 ALTER。 (请参阅该博客链接。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM