SQL ORDER BY 一个字符串值:它在比较什么? (区分大小写?)

SQL ORDER BY a string value: What is it comparing? (Case sensitive?)

我想知道当我们使用 ORDER BY 语句时 SQL 到底在比较什么。更具体地说,我对比较字符串时的比较感兴趣。据说它是按字母顺序排序的,但它实际上比较的是什么?

我的直觉告诉我它可能是比较从左边开始的字符的 ASCII 值,这也意味着排序区分大小写('Btest' 会小于 'atest'),但我找不到证实这一点的消息来源。

这类题考起来简单
我在这里测试的是 dbFiddle:你可以 运行 相同的脚本,如果需要的话,在你的数据库中使用其他值来检查你的本地设置、排序规则等。

create table sortable(
val varchar(10));
insert into sortable values
('A'),('B'),('a'),('b');
✓

✓
SELECT val
FROM sortable
ORDER BY val;
| val |
| :-- |
| A   |
| a   |
| B   |
| b   |

db<>fiddle here

如果您想切换到 ASCII 代码排序,您可以更改顺序以按字符的二进制值排序,方法如下:

SELECT id, random_varchar FROM table ORDER BY NLSSORT(random_varchar, 'NLS_SORT = BINARY')

在MySQL中,取决于有效排序规则。排序规则是一组规则,用于确定字符在有序集中的位置以及哪些字符被视为相等,并且通常涉及自然语言规则。例如,西班牙语曾经将 ch 作为位于 cd 之间的独立字母,然后切换为单独的 ch; MySQL 两者都有排序规则。

您可以使用 these commands 查看可用的排序规则:

SHOW COLLATION; -- Display all
SHOW COLLATION WHERE charset = 'utf8mb4'; -- Filter by encoding
Collation Charset Id Default Compiled Sortlen Pad_attribute
utf8mb4_0900_ai_ci utf8mb4 255 Yes Yes 0 NO PAD
utf8mb4_0900_as_ci utf8mb4 305 Yes 0 NO PAD
utf8mb4_0900_as_cs utf8mb4 278 Yes 0 NO PAD
utf8mb4_0900_bin utf8mb4 309 Yes 1 NO PAD
utf8mb4_bin utf8mb4 46 Yes 1 PAD SPACE
utf8mb4_croatian_ci utf8mb4 245 Yes 8 PAD SPACE
utf8mb4_cs_0900_ai_ci utf8mb4 266 Yes 0 NO PAD
utf8mb4_cs_0900_as_cs utf8mb4 289 Yes 0 NO PAD
utf8mb4_czech_ci utf8mb4 234 Yes 8 PAD SPACE
utf8mb4_danish_ci utf8mb4 235 Yes 8 PAD SPACE

[...]

MySQL 中的排序规则名称使用一些常见的子字符串来表示某些特征:

  • ci / cs 不区分大小写/区分大小写
  • ai / as 对于重音敏感/重音不敏感

...和其他一些 (full list here)。

在MySQL中,您可以设置多个级别的排序规则:

  • 服务器
  • 数据库
  • Table
  • 连接
  • SQL
  • 中的各个字符串

所以你总是得到一个,无论是显式的还是隐式的。