SQLite/Room ORDER BY 与 CASE 语句会忽略列 COLLATE

发布于 2025-01-11 01:59:44 字数 1505 浏览 0 评论 0原文

关于使用 SQLite 的 ORDER BY 子句中的 CASE 语句,我有一些不明白的地方(最初我在 Android Room 中使用它,但它并不特定于此) 。

这是问题的精华。查询 1 返回我所期望的内容(不区分大小写的有序列表)。而查询 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;
idstuff
10
2a
4A
3z
5Z

查询 #2

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

在 DB Fiddle 上查看

Theres something I don't understand with regards to a CASE statement in a ORDER BY clause using SQLite (initially I was using it with Android Room but its not specific to that).

This is a distillation of the problem. Query 1 returns what I was expecting (a case insensitive, ordered list of the stuff). Whereas Query 2 appears to ignore the column's COLLATE NOCASE. Why is that?

Thanks!

Schema (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");

Query #1

SELECT *
FROM test
ORDER BY
    stuff ASC;
idstuff
10
2a
4A
3z
5Z

Query #2

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

View on DB Fiddle

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一梦浮鱼 2025-01-18 01:59:44

任何 CASE 表达式 的结果都是一个表达式,甚至如果它的返回值是对列的简单引用,例如 THEN stuff
对于此返回的表达式,没有显式定义整理序列,因此出于以下目的ORDER BY 子句比较所使用的整理顺序是 BINARY

如果 ORDER BY 子句只是:

ORDER BY stuff || '' ASC

上面的表达式stuff || '' 仅返回列 stuff 的值,但它仍然被视为表达式,并且 BINARY 整理序列将为

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

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

请参阅演示

The result of any CASE expression is an expression, even if its return value is a simple reference to a column like THEN stuff.
For this returned expression there is no explicitly defined Collating Sequence, so for the purposes of the ORDER BY clause comparisons the collating sequence that is used is BINARY.

The same would happen if the ORDER BY clause was just:

ORDER BY stuff || '' ASC

The above expression stuff || '' returns just the value of the column stuff, but still it is considered an expression and the BINARY collating sequence will be used.

If you want to apply a specific collating sequence to the result of the CASE expression you must use it explicitly in the ORDER BY clause:

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

See the demo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文