2011-02-02 80 views
4

我只是想知道是否有人遇到SQLite(3.7.4)中的情況,其中查詢將返回一組結果,並且當它變成子查詢時結果是完全不同?我發現了一個更復雜的查詢問題,但這裏是一個演示相同的行爲一個簡單的例子:SQLite外部查詢返回內部查詢中找不到的結果

數據庫設置:

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郵件列表報告這個錯誤,並將此作爲解決方法。

回答

1

我可以驗證它是否發生在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增加了很多操作,內聯和優化內部查詢(不正確)。

+0

感謝您的確認。現在我已經知道了,我將通過適當的渠道將此報告爲錯誤。 – dkubb 2011-02-02 18:10:30