sql - 为什么以大写字母开头的字符排在以小写字母开头的字符之前?
问题描述
我在SQL中做一些基本的排序,我很久以前就学会了:以大写字母开头的名称在以小写字母开头的名称之前排序。例子:
sqlite> create table letters (letter text);
sqlite> insert into letters values ('A');
sqlite> insert into letters values ('C');
sqlite> insert into letters values ('b');
sqlite> insert into letters values ('d');
sqlite> select * from letters order by letter asc;
输出:
A
C
b
d
在这种情况下,我们需要输入:sqlite> select * from letters order by letter collate nocase asc;
,这将给出预期的输出:
A
b
C
d
但我的问题是为什么它是这样排序的?我试图找到答案,但我失败了。我唯一的猜测是 ASCII 为"A"=65,而"a"=97。65<97,意思是"A"
在之前存储"a"
。操作系统真的以这种方式工作还是我还缺少其他东西?它是如何在幕后工作的?
解决方案
数据类型文档中描述了 Sqlite3 如何选择比较函数来排序和比较字符串。
基本上,如果您没有COLLATE
在表达式或相关列定义中使用关键字显式声明一个,它会使用BINARY
排序规则模式,就像 Cmemcmp()
函数用于比较值一样 - 它查看第一个字节的单个字节不同。
Sqlite 使用 Unicode 存储文本值(使用 UTF-8 或 UTF-16,请参阅PRAGMA encoding
)。Unicode 的前 127 个代码点与 ASCII 相同,因此具有较低值的大写英文字母将在排序规则中排在小写字母之前BINARY
。
烦人的是,这意味着可以根据底层编码以不同的方式对相同的数据进行排序:
$ sqlite3 test1.db
sqlite> PRAGMA encoding='UTF-16LE';
sqlite> CREATE TABLE test(word TEXT);
sqlite> INSERT INTO test VALUES ('A'), ('a'), ('B'), ('b'), (char(0x1F355));
sqlite> SELECT word, hex(word), unicode(word) FROM test ORDER BY word;
word hex(word) unicode(word)
---- --------- -------------
3CD855DF 127829
A 4100 65
B 4200 66
a 6100 97
b 6200 98
sqlite> .quit
$ sqlite3 test2.db
sqlite> PRAGMA encoding='UTF-16BE';
sqlite> CREATE TABLE test(word TEXT);
sqlite> INSERT INTO test VALUES ('A'), ('a'), ('B'), ('b'), (char(0x1F355));
sqlite> SELECT word, hex(word), unicode(word) FROM test ORDER BY word;
word hex(word) unicode(word)
---- --------- -------------
A 0041 65
B 0042 66
a 0061 97
b 0062 98
D83CDF55 127829
sqlite> .quit
$ sqlite3 test3.db
sqlite> PRAGMA encoding='UTF-8';
sqlite> CREATE TABLE test(word TEXT);
sqlite> INSERT INTO test VALUES ('A'), ('a'), ('B'), ('b'), (char(0x1F355));
sqlite> SELECT word, hex(word), unicode(word) FROM test ORDER BY word;
word hex(word) unicode(word)
---- --------- -------------
A 41 65
B 42 66
a 61 97
b 62 98
F09F8D95 127829
推荐阅读
- javacard - 选择 Java Card Applet 并返回 0x61XX 而不是 0x9000
- javascript - React 中的 Material-UI Grid 每个元素的唯一 ID
- statistics - 如何量化包含 0 基值的数据集的变化幅度?
- netsuite - NetSuite:如何使用 suitesql 或 REST 获取自定义字段列表?
- php - PHP中的排行榜/高分
- node.js - 如果未在隐身模式下打开 PM2,则 PM2 会拒绝连接
- html - Excel VBA:通常通过 datepicker-popup 使用鼠标命令的 IE 日期选择/操作
- django - 是否可以在 zappa 中使用 lambda 层?
- c++ - Eclipse 找不到 MinGW/无法在 Eclipse 上设置 C++
- java - 当在行中执行某些操作时重新加载页面后更改表中的行数时如何在 selenium java 中处理 webtable