2017-04-06 138 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

相关问题