Firebird 与其他字符集的排序顺序
Firebird sort order with other character set
此查询中的排序不考虑符号,只考虑字母:
SELECT CAST(Text AS VARCHAR(20) CHARACTER SET ISO8859_1) COLLATE NO_NO Result FROM (
select CAST('_Anon' AS VARCHAR(20)) COLLATE UNICODE_CI_AI as Text from RDB$DATABASE
UNION
SELECT CAST('Abba' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE
UNION
SELECT CAST('Beatles' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE)
ORDER BY Result
预期排序顺序(任何字母前非字母数字):
_Anon
Abba
Beatles
但我得到:
Abba
_Anon
Beatles
排序规则无关紧要。如果你删除 "COLLATE NO_NO" 它仍然排序错误。
编辑:发现排序规则 ES_ES 对此进行了正确排序,但无法对挪威语字符进行排序。
这是一个错误还是我在此查询中遗漏了什么?
我想要做的是在挪威语中获得正确的排序顺序,UNICODE_CI_AI 中的排序规则 none 为我提供了正确的顺序。
更新:用另一个子查询扩展示例,以便更清楚地显示要点。
查看整理的标记提示为我指出了解决方案的方向。
我确实认为这是一个错误,所以我打算向 firebirdsql 提交错误报告,但发现 it's a "Won't fix" and the workaround below is the official fix。
在定义的所有基本排序规则中,ES_* 是唯一具有属性:SPECIALS-FIRST=1 集的排序规则。事实上,它是唯一具有任何属性集的排序规则。
并且 attribute defines 特殊字符应排在字母数字字符之前。
因此解决方法是基于 NO_NO 排序规则创建一个新排序规则:
CREATE COLLATION NO_NO_NOPAD_CI_SF
FOR ISO8859_1
FROM NO_NO
NO PAD
CASE INSENSITIVE
'SPECIALS-FIRST=1';
然后像这样使用新的排序规则:
SELECT CAST(Text AS VARCHAR(20) CHARACTER SET ISO8859_1) COLLATE NO_NO_NOPAD_CI_NUM_SF Result FROM (
select CAST('_Anon' AS VARCHAR(20)) COLLATE UNICODE_CI_AI as Text from RDB$DATABASE
UNION
SELECT CAST('Abba' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE
UNION
SELECT CAST('Beatels' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE)
ORDER BY Result
产生预期结果:
_Anon
Abba
Beatles
此查询中的排序不考虑符号,只考虑字母:
SELECT CAST(Text AS VARCHAR(20) CHARACTER SET ISO8859_1) COLLATE NO_NO Result FROM (
select CAST('_Anon' AS VARCHAR(20)) COLLATE UNICODE_CI_AI as Text from RDB$DATABASE
UNION
SELECT CAST('Abba' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE
UNION
SELECT CAST('Beatles' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE)
ORDER BY Result
预期排序顺序(任何字母前非字母数字):
_Anon
Abba
Beatles
但我得到:
Abba
_Anon
Beatles
排序规则无关紧要。如果你删除 "COLLATE NO_NO" 它仍然排序错误。
编辑:发现排序规则 ES_ES 对此进行了正确排序,但无法对挪威语字符进行排序。
这是一个错误还是我在此查询中遗漏了什么?
我想要做的是在挪威语中获得正确的排序顺序,UNICODE_CI_AI 中的排序规则 none 为我提供了正确的顺序。
更新:用另一个子查询扩展示例,以便更清楚地显示要点。
查看整理的标记提示为我指出了解决方案的方向。
我确实认为这是一个错误,所以我打算向 firebirdsql 提交错误报告,但发现 it's a "Won't fix" and the workaround below is the official fix。
在定义的所有基本排序规则中,ES_* 是唯一具有属性:SPECIALS-FIRST=1 集的排序规则。事实上,它是唯一具有任何属性集的排序规则。
并且 attribute defines 特殊字符应排在字母数字字符之前。
因此解决方法是基于 NO_NO 排序规则创建一个新排序规则:
CREATE COLLATION NO_NO_NOPAD_CI_SF
FOR ISO8859_1
FROM NO_NO
NO PAD
CASE INSENSITIVE
'SPECIALS-FIRST=1';
然后像这样使用新的排序规则:
SELECT CAST(Text AS VARCHAR(20) CHARACTER SET ISO8859_1) COLLATE NO_NO_NOPAD_CI_NUM_SF Result FROM (
select CAST('_Anon' AS VARCHAR(20)) COLLATE UNICODE_CI_AI as Text from RDB$DATABASE
UNION
SELECT CAST('Abba' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE
UNION
SELECT CAST('Beatels' AS VARCHAR(20)) COLLATE UNICODE_CI_AI AS Text from RDB$DATABASE)
ORDER BY Result
产生预期结果:
_Anon
Abba
Beatles