You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL为何部分排序区分大小写、部分不区分?

PostgreSQL v11.10 排序行为解析

问题场景

执行以下SQL操作:

create temp table test (first_name text, last_name text);
insert into test values
  ('Hanna', 'Beat'),
  ('JOAN', 'BEET'),
  ('Mark', 'Bernstein'),
  ('ALFRED', 'DOE'),
  ('henry', 'doe'),
  ('Henry', 'Doe'),
  ('Dennis', 'Doe');
select last_name, first_name from test order by last_name, first_name;

得到实际结果:

last_name | first_name 
-----------+------------
 Beat      | Hanna
 BEET      | JOAN
 Bernstein | Mark
 doe       | henry
 Doe       | Dennis
 Doe       | Henry
 DOE       | ALFRED
(7 rows)

困惑点:前三条排序看似不区分大小写,后四条却区分大小写,既不符合完全区分大小写的预期,也不符合完全不区分大小写的预期。

环境信息:

# show lc_collate; show lc_ctype;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

  lc_ctype   
-------------
 en_US.UTF-8
(1 row)

原因解析

核心是en_US.UTF-8排序规则(由lc_collate控制)的双层比较逻辑:

  • 第一层:不区分大小写的字典序比较
    当两个字符串的「不区分大小写版本」字典序不同时,直接按该字典序排序,忽略大小写。比如:

    • Beat和BEET的不区分大小写版本是beat和beet,beat的第三个字符a字典序小于beet的e,因此Beat排在BEET前;
    • BEET和Bernstein的不区分大小写版本是beet和bernstein,beet的第三个字符e小于bernstein的r,因此BEET排在Bernstein前。
      这就是前三条看起来「不区分大小写」的原因。
  • 第二层:区分大小写的精细排序
    当两个字符串的「不区分大小写版本」完全相同时,会进一步按字符的大小写权重排序:小写字符权重低于大写字符,因此全小写字符串排在最前,首大写次之,全大写最后。

    同时你的排序语句是order by last_name, first_name,当last_name优先级相同时(比如两条Doe),会按first_name的字典序排序:Dennis的字典序小于Henry,因此Doe | Dennis排在Doe | Henry前。

总结

实际结果是en_US.UTF-8排序规则的正常表现:先按不区分大小写的字典序分组排序,组内再区分大小写并结合后续排序字段细化顺序。

内容的提问来源于stack exchange,提问作者mbork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:01:14