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
作为位于 c
和 d
之间的独立字母,然后切换为单独的 c
和 h
; 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
中的各个字符串
所以你总是得到一个,无论是显式的还是隐式的。
我想知道当我们使用 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
作为位于 c
和 d
之间的独立字母,然后切换为单独的 c
和 h
; 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 中的各个字符串
所以你总是得到一个,无论是显式的还是隐式的。