⌘+k ctrl+k
1.4 (LTS)
搜索快捷键 cmd + k | ctrl + k
排序规则

排序规则提供了执行引擎对文本进行排序或比较的规则。排序规则对于本地化非常有用,因为不同语言或不同国家对文本排序的规则各不相同。这些排序方式通常互不兼容。例如,在英语中,字母 y 位于 xz 之间。然而,在立陶宛语中,字母 y 位于 ij 之间。因此,系统支持多种不同的排序规则。用户在执行排序和比较操作时必须选择他们想要使用的排序规则。

默认情况下,使用 BINARY(二进制)排序规则。这意味着字符串仅根据其二进制内容进行排序和比较。这对于标准 ASCII 字符(即字母 A-Z 和数字 0-9)是有意义的,但对于特殊的 Unicode 字符通常意义不大。不过,它是目前执行排序和比较最快的方法。因此,除非有特殊要求,否则建议保留使用 BINARY 排序规则。

BINARY 排序规则也可以通过别名 CPOSIX 使用。

警告:DuckDB 中的排序规则支持存在一些已知限制,并且有若干改进计划

使用排序规则

在 DuckDB 的独立安装版中,包含三种排序规则:NOCASENOACCENTNFCNOCASE 排序规则在比较字符时忽略大小写。NOACCENT 排序规则在比较字符时忽略变音符号。NFC 排序规则执行 NFC 规范化比较,有关更多信息,请参阅 Unicode 规范化

SELECT 'hello' = 'hElLO';
false
SELECT 'hello' COLLATE NOCASE = 'hElLO';
true
SELECT 'hello' = 'hëllo';
false
SELECT 'hello' COLLATE NOACCENT = 'hëllo';
true

排序规则可以通过点运算符串联组合使用。但请注意,并非所有排序规则都可以组合在一起。通常,NOCASE 排序规则可以与任何其他排序器组合,但大多数其他排序规则则无法组合。

SELECT 'hello' COLLATE NOCASE = 'hElLÖ';
false
SELECT 'hello' COLLATE NOACCENT = 'hElLÖ';
false
SELECT 'hello' COLLATE NOCASE.NOACCENT = 'hElLÖ';
true

默认排序规则

到目前为止,我们看到的排序规则都是针对每个表达式指定的。也可以在全局数据库级别或基础表列上指定默认排序器。PRAGMA default_collation 可用于指定全局默认排序器。如果未指定其他规则,将使用此默认排序器。

SET default_collation = NOCASE;
SELECT 'hello' = 'HeLlo';
true

创建表时也可以按列指定排序规则。当该列用于比较时,将使用该列指定的排序规则来执行比较。

CREATE TABLE names (name VARCHAR COLLATE NOACCENT);
INSERT INTO names VALUES ('hännes');
SELECT name
FROM names
WHERE name = 'hannes';
hännes

不过,在这里要小心,因为不同的排序规则无法组合使用。当您想要比较具有不同排序规则的列时,这可能会引发问题。

SELECT name
FROM names
WHERE name = 'hannes' COLLATE NOCASE;
ERROR: Cannot combine types with different collation!
CREATE TABLE other_names (name VARCHAR COLLATE NOCASE);
INSERT INTO other_names VALUES ('HÄNNES');
SELECT names.name AS name, other_names.name AS other_name
FROM names, other_names
WHERE names.name = other_names.name;
ERROR: Cannot combine types with different collation!

我们需要手动覆盖排序规则

SELECT names.name AS name, other_names.name AS other_name
FROM names, other_names
WHERE names.name COLLATE NOACCENT.NOCASE = other_names.name COLLATE NOACCENT.NOCASE;
name other_name
hännes HÄNNES

ICU 排序规则

到目前为止我们看到的排序规则与区域无关,也不遵循任何特定的区域规则。如果您希望遵循特定区域或语言的规则,则需要使用 ICU 排序规则之一。为此,您需要加载 ICU 扩展

加载此扩展程序会将多种特定于语言和地区的排序规则添加到您的数据库中。可以使用 PRAGMA collations 命令或通过查询 pragma_collations 函数来查询这些规则。

PRAGMA collations;
SELECT list(collname) FROM pragma_collations();
[af, am, ar, ar_sa, as, az, be, bg, bn, bo, br, bs, ca, ceb, chr, cs, cy, da, de, de_at, dsb, dz, ee, el, en, en_us, eo, es, et, fa, fa_af, ff, fi, fil, fo, fr, fr_ca, fy, ga, gl, gu, ha, haw, he, he_il, hi, hr, hsb, hu, hy, icu_noaccent, id, id_id, ig, is, it, ja, ka, kk, kl, km, kn, ko, kok, ku, ky, lb, lkt, ln, lo, lt, lv, mk, ml, mn, mr, ms, mt, my, nb, nb_no, ne, nfc, nl, nn, noaccent, nocase, om, or, pa, pa_in, pl, ps, pt, ro, ru, sa, se, si, sk, sl, smn, sq, sr, sr_ba, sr_me, sr_rs, sv, sw, ta, te, th, tk, to, tr, ug, uk, ur, uz, vi, wae, wo, xh, yi, yo, yue, yue_cn, zh, zh_cn, zh_hk, zh_mo, zh_sg, zh_tw, zu]

这些排序规则的使用方式与之前的排序规则相同。它们也可以与 NOCASE 排序规则组合使用。例如,要使用德语排序规则,可以使用以下代码片段

CREATE TABLE strings (s VARCHAR COLLATE DE);
INSERT INTO strings VALUES ('Gabel'), ('Göbel'), ('Goethe'), ('Goldmann'), ('Göthe'), ('Götz');
SELECT * FROM strings ORDER BY s;
"Gabel", "Göbel", "Goethe", "Goldmann", "Göthe", "Götz"
© 2025 DuckDB 基金会,阿姆斯特丹,荷兰
行为准则 商标使用指南