SQLite/Room 带有 CASE 语句的 ORDER BY 忽略列 COLLATE

SQLite/Room ORDER BY with a CASE statement ignores column COLLATE

关于使用 SQLite 的 ORDER BY 子句中的 CASE 语句,我有些不明白(最初我将它与 Android Room 一起使用,但它不特定于那个)。

这是问题的提炼。查询 1 returns 我所期待的(不区分大小写的有序列表)。而查询 2 似乎忽略了该列的 COLLATE NOCASE。这是为什么?

谢谢!

架构 (SQLite v3.30)

CREATE TABLE "test" (
    "id"    INTEGER,
    "stuff" TEXT COLLATE NOCASE,
    PRIMARY KEY("id" AUTOINCREMENT)
);

INSERT INTO test (stuff) VALUES ("0");
INSERT INTO test (stuff) VALUES ("a");
INSERT INTO test (stuff) VALUES ("z");
INSERT INTO test (stuff) VALUES ("A");
INSERT INTO test (stuff) VALUES ("Z");

查询#1

SELECT *
FROM test
ORDER BY
    stuff ASC;
id stuff
1 0
2 a
4 A
3 z
5 Z

查询 #2

SELECT * 
FROM test
ORDER BY 
    CASE WHEN true THEN stuff END ASC;
id stuff
1 0
4 A
5 Z
2 a
3 z

View on DB Fiddle

任何 CASE expression 的结果都是 表达式 ,即使它的 return 值是对像 THEN stuff 这样的列的简单引用.
对于此 returned 表达式,没有显式定义 Collating Sequence,因此为了 ORDER BY 子句比较的目的,使用的整理顺序是 BINARY.

如果 ORDER BY 子句只是:

,也会发生同样的情况
ORDER BY stuff || '' ASC

上面的表达式 stuff || '' return 只是列 stuff 的值,但它仍然被认为是一个 表达式 并且BINARY 将使用整理顺序。

如果要将特定的整理序列应用于 CASE 表达式的结果,则必须在 ORDER BY 子句中明确使用它:

SELECT * 
FROM test 
ORDER BY CASE WHEN true THEN stuff END COLLATE NOCASE ASC;

demo.