2017-04-06 137 views
0

我對SQL很陌生,但試圖修正SQL-Query的輸出。然而,這個問題並不涉及這個bug,而是爲什麼SQLite3在它應該時不會產生錯誤。爲什麼SQLite3不會產生錯誤

我有查詢字符串,看起來像:

QueryString = ("SELECT e.event_id, " 
    "count(e.event_id), " 
    "e.state, " 
    "MIN(e.boot_time) AS boot_time, " 
    "e.time_occurred, " 
    "COALESCE(e.info, 0) AS info " 
    "FROM events AS e " 
    "JOIN leg ON leg.id = e.leg_id " 
    "GROUP BY e.event_id " 
    "ORDER BY leg.num_leg DESC, " 
    "e.event_id ASC;\n" 
    ) 

這將產生沒有錯誤的輸出。

我不明白爲什麼當我GROUP BY e.event_id和e.state和e.time_occurred不包含聚合函數並且不是GROUP BY語句的一部分時沒有錯誤?

e.state是一個字符串列。 e.time_occurred是一個整數列。

我在Python中使用QueryString。

+0

這是SQLite和MySQL的「特性」。在MySQL中,您可以使用服務器中的嚴格模式設置進行更正。也許在SQLite中也是如此... –

+0

好的......你能詳細說明這個功能的預期系統行爲嗎? – Orpedo

回答

1

SQLite和MySQL允許聚合查詢中裸露的列。這在documentation解釋:

在上面的查詢中,「a」列是BY子句組的一部分和 所以輸出的每行包含用於「A」的不同值中的一個。 「c」列包含在sum()聚合函數內,因此輸出列是具有「a」的相同值的行中所有「c」值的總和。但裸列「b」的結果是什麼? 的答案是,「b」結果將是形成聚合的 輸入行之一中「b」的值。問題是你通常做 不知道哪個輸入行被用來計算「b」,所以在很多情況下 「b」的值是未定義的。

您的特定查詢的是:

SELECT e.event_id, count(e.event_id), e.state, MIN(e.boot_time) AS boot_time, 
     e.time_occurred, COALESCE(e.info, 0) AS info 
FROM events AS e JOIN 
    leg 
    ON leg.id = e.leg_id " 
GROUP BY e.event_id 
ORDER BY leg.num_leg DESC, e.event_id ASC; 

如果e.event_idevents的主鍵,那麼這個語法甚至被ANSI標準的支持,因爲event_id足以在唯一確定的其他列排在events

2

在被誤導爲與MySQL兼容的嘗試中,這是允許的。 (非聚合列值來自組中的某個隨機行)

由於SQLite 3.7.11使用min()或max()guarantees表示非聚合列中的值來自具有組中的最小值/最大值。

1

如果e.event_id是表中的PRIMARY或UNIQUE鍵,則e.time_occurred被稱爲「功能依賴」,甚至不會在其他SQL兼容的DBMS中引發錯誤。

但是,SQLite尚未實現函數依賴。對於SQLite(和MySQL),即使對於而不是的列在功能上依賴於GROUP BY列,也不會引發錯誤。

SQLite(和MySQL)只需從結果集中選擇一個隨機行以填充(在SQLite術語中)「裸列」,請參閱this

相關問題