PostgreSQL如何在SELECT查询中指定排序规则兼容土英字符(Dapper)
在PostgreSQL中实现土耳其语与英语字符兼容的模糊匹配
要在SELECT查询里靠排序规则实现你要的字符匹配效果,按下面的方法来:
1. 先确认土耳其语排序规则存在
先查下数据库里有没有土耳其语的排序规则,跑这个语句:
SELECT collname, collprovider FROM pg_collation WHERE collname LIKE 'tr%';
一般会返回tr_TR.utf8(libc提供)或者tr_tr.utf8(ICU提供)这类结果,随便用哪个都行。
2. 用土耳其语排序规则做模糊匹配
你要让u和ü、i和ı这类字符在匹配时被当成一样的,有两种靠谱方案:
方案一:unaccent函数+土耳其语排序规则
unaccent能去掉字符的重音标记,再配合土耳其语排序规则处理ı转i这类特殊情况,查询语句这么写:
SELECT * FROM students WHERE unaccent(name) COLLATE "tr_TR.utf8" LIKE unaccent('%Huseyin%') COLLATE "tr_TR.utf8";
提一句:如果数据库没装unaccent扩展,先跑CREATE EXTENSION unaccent;启用它。
方案二:用ICU的重音不敏感排序规则
如果你的PostgreSQL编译时开了ICU支持,直接用忽略重音的土耳其语排序规则就行,比如tr-TR-x-ks-level2(level2就是忽略重音的意思):
SELECT * FROM students WHERE name COLLATE "tr-TR-x-ks-level2" LIKE '%Huseyin%' COLLATE "tr-TR-x-ks-level2";
这种规则会自动把ü当u、ı当i,连大小写差异也能忽略,直接满足你的匹配需求。
额外提醒
- 要是用libc的
tr_TR.utf8排序规则,默认是区分重音的,光靠LIKE匹配不了带重音的字符,必须结合unaccent。 - 想提升查询速度的话,可以给处理后的字段建个索引:
CREATE INDEX idx_students_name_unaccent_tr ON students USING btree (unaccent(name) COLLATE "tr_TR.utf8");
内容的提问来源于stack exchange,提问作者AnilKilic
相关产品推荐
相关产品推荐

