gpt4 book ai didi

SQLite 外部查询返回在内部查询中找不到的结果

转载 作者:行者123 更新时间:2023-12-03 16:27:01 25 4
gpt4 key购买 nike

我只是想知道是否有人在 SQLite (3.7.4) 中遇到过这样的情况,查询将返回一组结果,而当它变成子查询时,结果完全不同?我在一个更复杂的查询中发现了这个问题,但这里有一个更简单的示例,它演示了相同的行为:

数据库设置:

CREATE TABLE "test" ("letter" VARCHAR(1) PRIMARY KEY, "number" INTEGER NOT NULL);

INSERT INTO "test" ("letter", "number") VALUES('b', 1);
INSERT INTO "test" ("letter", "number") VALUES('a', 2);
INSERT INTO "test" ("letter", "number") VALUES('c', 2);

初始查询:
SELECT "letter", "number" FROM "test" ORDER BY "letter", "number" LIMIT 1;

这将返回 a|2 ,结果的第二行正如您所期望的那样,因为我们正在对字母和数字进行排序。然而,这是我没想到的:

作为子查询的初始查询:
SELECT DISTINCT "number" FROM (SELECT "letter", "number" FROM "test" ORDER BY "letter", "number" LIMIT 1) AS "test";

这将返回 1 ,这完全不是我所期望的。我期望看到的是 2 .我对子查询如何工作的理解是,它应该返回与内部查询已实现的结果相同的结果,并将外部查询应用于这些结果(即使我意识到数据库在必要时不会实现结果) .

我的假设不正确吗?我在 PostgreSQL 和 MySQL 中测试了相同的查询,它按我的预期工作(即它返回 2 )。在我看来,我遇到了 SQLite 如何折叠子查询的错误,但我不确定。

重申一下,上面的例子是从我实际做的事情中简化出来的。我不只是在返回单行的子查询上使用 DISTINCT,而是它返回许多行,其中一些行具有相同的列值,因此我需要 DISTINCT。上面的例子是我能想到的最简单的方法来演示正在发生的事情。

编辑:我能够通过添加 OFFSET 0 来禁用不正确的子查询折叠到内部查询,例如
SELECT DISTINCT "number" FROM (SELECT "letter", "number" FROM "test" ORDER BY "letter", "number" LIMIT 1 OFFSET 0) AS "test";

我将通过 SQLite 邮件列表将此报告为错误,并将其作为解决方法。

最佳答案

我可以验证它是否也发生在 Firefox 的 SQLite 附加组件中。

如果有任何安慰,这个表格有效:

SELECT DISTINCT "number" FROM (SELECT "letter", "number" FROM "test"
ORDER BY "letter", "number") AS "test" ORDER BY "letter" LIMIT 1;

我相信 SQLite 规范会忽略内部查询中的 LIMIT 子句并将其迁移到外部。无限制:
SELECT DISTINCT "number" FROM (SELECT "letter", "number" FROM "test"
ORDER BY "letter", "number") AS "test";

它返回
1
2
(2 rows)

有趣的是,这也返回了正确的结果
SELECT number FROM (SELECT letter, number FROM test
ORDER BY letter, number LIMIT 1) AS test;

可以使用 EXPLAIN 比较这两个计划。
DESCRIBE 正在添加大量操作,内联和优化内部查询(错误地)。

关于SQLite 外部查询返回在内部查询中找不到的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4870293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com