va.*_*va. 2 postgresql collation sql-order-by alphabetical-sort accent-sensitive
如何按拉脱维亚语字母顺序对 PostgreSQL 中的文本进行排序,以便任何不带重音的字母始终位于带重音的字母之前?
\n例如这个
\nselect * from (\n select \'b\xc4\x81\' as name\n union select \'\xc4\x81a\'\n union select \'ac\'\n union select \'\xc4\x80b\'\n union select \'\xc4\x80\'\n) t\norder by name COLLATE "lv-x-icu"\nRun Code Online (Sandbox Code Playgroud)\n回报\xc4\x80 \xc4\x81a \xc4\x80b ac b\xc4\x81
但预期结果是ac \xc4\x80 \xc4\x81a \xc4\x80b b\xc4\x81
我尝试创建一些自定义排序规则,但没有一个返回预期结果。
\n这是一个不寻常的要求。在自然语言排序规则(包括拉图维亚排序规则)中,字符串按不同步骤进行比较:
\n第一步,标点符号、大小写和重音符号将被忽略。如果字符串比较不同,则确定排序顺序。这就是所谓初级层次上的差异。
\n如果字符串在初级级别上相等,则仅忽略标点符号和大小写,但重音符号很重要。如果字符串比较不同,则确定排序顺序。这是中学层次上的区别。
\n如果二级字符串相等,则仅忽略标点符号,但重音符号和大小写很重要。这是第三级。
\n最后,如果字符串在第三级上相等,则标点符号(第四级)的差异很重要。
\n这解释了您看到的排序顺序:因为a < aa < ab < ac <ba在初级级别上,不考虑重音。
如果您愿意ac < \xc4\x80,您希望在初级级别上将重音视为不同的,就好像a和\xc4\x81是不同的字母一样。为此,您必须使用 ICU 排序规则并使用其他规则对其进行自定义。这只能从 v16 开始实现:
CREATE COLLATION latuvian_custom (\n PROVIDER = icu,\n LOCALE = 'lv',\n RULES = '& a < \xc4\x81 & A < \xc4\x80 & c < \xc4\x8d & C < \xc4\x8c & e < \xc4\x93 & E < \xc4\x92 & g < \xc4\xa3 & G < \xc4\xa2 & k < \xc4\xb7 & K < \xc4\xb6 & l < \xc4\xbc & L < \xc4\xbb & n < \xc5\x86 & N < \xc5\x85 & s < \xc5\xa1 & S < \xc5\xa0 & u < \xc5\xab & U < \xc5\xaa & z < \xc5\xbe & Z < \xc5\xbd'\n);\n\nselect * from (\n select 'b\xc4\x81' as name\n union select '\xc4\x81a'\n union select 'ac'\n union select '\xc4\x80b'\n union select '\xc4\x80'\n) t\norder by name COLLATE latuvian_custom;\n\n name \n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n ac\n \xc4\x80\n \xc4\x80b\n \xc4\x81a\n b\xc4\x81\n(5 rows)\nRun Code Online (Sandbox Code Playgroud)\n<这些规则引入了非重音字符和重音字符之间的主要级别差异 ( )。