假设我有一个包含两列的简单表:id(int)和name(varchar)。在此表中,我存储了一些波兰语的名称,例如:
1 | sępoleński
2 | świecki
3 | toruński
4 | Włocławek
现在,假设我想按名称对结果进行排序:
SELECT * FROM table ORDER BY name;
如果我有C语言环境,我会得到:
4 | Włocławek
1 | sępoleński
3 | toruński
2 | świecki
这是错误的,因为“ś”应该在“s”之后和“t”之前。如果我使用波兰语语言环境(pl_PL.UTF-8),我会得到:
1 | sępoleński
2 | świecki
3 | toruński
4 | Włocławek
这也不是我想要的,因为我希望以大写字母开头的名字首先就像在C语言环境中一样,如下所示:
4 | Włocławek
1 | sępoleński
2 | świecki
3 | toruński
我该怎么做?
答案 0 :(得分:2)
如果您想要自定义排序,则必须定义一些以某种方式修改值的函数,以便修改后的值的自然顺序符合您的要求。
例如,您可以附加一些字符或字符串,其值以大写字母开头:
CREATE OR REPLACE FUNCTION mysort(text) returns text IMMUTABLE as $$
SELECT CASE WHEN substring($1 from 1 for 1) =
upper( substring($1 from 1 for 1)) then 'AAAA' || $1 else $1 END
;
$$ LANGUAGE SQL;
然后
SELECT * FROM table ORDER BY mysort(name);
这不是万无一失(当然,你可能想把'AAA'换成更合适的东西)并且会伤害性能。
答案 1 :(得分:1)
如果您希望它有效,则需要创建另一个“自然”正确排序的列(例如,甚至在C语言环境中),并将其用作排序标准。为此,您应该使用strxfrm C库函数的方法。作为您的方法的直接strxfrm表,用两个ASCII字母替换每个字母:'s'将变为's0','ś'将变为's1'。然后'świecki'变为's1w0i0e0c0k0i0',常规ASCII排序将对其进行正确排序。
如果您不想创建单独的列,可以尝试在where子句中使用函数:
SELECT * FROM table ORDER BY strxfrm(name);
这里,strxfrm需要用适当的功能替换。你自己写一个,或者你使用标准的translate函数(虽然这不支持用其中两个替换一个字符,所以你需要一些更复杂的转换)。