[英]PostgreSQL sort order affected by succeeding characters
我想對test last name
和test2 last name
進行排序,以便前者出現在后者之前。 我的理解是,每個字符都是從左到右進行比較,直到它們不同,因此第一個不同字符之后的字符不再重要。 但是,如下所示, test
在test2
之前,但只要我 append 另一個字符,順序就會改變。 為什么會這樣? 我應該使用什么排序規則來獲得所需的訂單? 請注意,將它們轉換為bytea
會產生所需的順序。
test=# SELECT 'test last name' < 'test2 last name' COLLATE "en_US";
?column?
----------
f
(1 row)
test=# SELECT 'test last' < 'test2 last' COLLATE "en_US";
?column?
----------
f
(1 row)
test=# SELECT 'test ' < 'test2 ' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test' < 'test2' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2 ' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2 ' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2 ' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2 l' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test ' < 'test2 l' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test l' < 'test2 l' COLLATE "en_US";
?column?
----------
f
(1 row)
test=# SELECT 'test l' < 'test2l' COLLATE "en_US";
?column?
----------
f
(1 row)
test=# SELECT 'test ' < 'test2l' COLLATE "en_US";
?column?
----------
t
(1 row)
test=# SELECT 'test last name'::bytea < 'test2 last name'::bytea;
?column?
----------
t
(1 row)
空格是 ICU 整理中的特殊字符。
看演示: https://www.unicode.org/reports/tr10/#Variable_Weighting_Examples
也在這里: http://www.unicode.org/reports/tr35/tr35-collation.html#table-collation-settings
簡單解釋: https://unicode-org.github.io/icu/userguide/collation/customization/ignorepunct.html#shift-trimmed
您可以進行以下測試:
CREATE COLLATION coll_shifted(provider = icu, locale = 'en-u-ka-shifted');
CREATE COLLATION coll_noignore(provider = icu, locale = 'en-u-ka-noignore');
SELECT 'test last name' < 'test2 last name' COLLATE coll_shifted
union all
SELECT 'test last name' < 'test2 last name' COLLATE coll_noignore
union all
SELECT 'test last name' < 'test2 last name' COLLATE "en_US";
如果您只想通過代碼指針進行比較,則可以使用 COLLATE "C" 或 COLLATE "POSIX"。
這就是自然語言排序的工作原理。 如果要逐個字符進行比較並使空格字符與其他字符一樣,請使用 C 排序規則:
SELECT 'test last name' < 'test2 last name' COLLATE "C";
?column?
══════════
t
(1 row)
但是如果'Z' < 'a'
不要抱怨......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.