我对SQL很新,但试图修改SQL-Query的输出。然而,这个问题并不涉及错误,而是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 :(得分:2)
在误导的与MySQL兼容的尝试中,这是允许的。 (非聚合列值来自组中的某个随机行。)
自SQLite 3.7.11以来,使用min()或max()guarantees,非聚合列中的值来自组中具有最小/最大值的行。
答案 1 :(得分:1)
SQLite和MySQL允许在聚合查询中使用裸列。这在documentation:
中有解释在上面的查询中,“a”列是GROUP BY子句的一部分 所以输出的每一行都包含一个“a”的不同值。 “c”列包含在sum()聚合函数中,因此 输出列是具有的行中所有“c”值的总和 “a”的值相同。但裸列“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_id
是events
中的主键,那么ANSI标准甚至支持这种语法,因为event_id
足以唯一地定义{中的一行中的其他列{1}}。
答案 2 :(得分:1)
如果e.event_id
是表的PRIMARY或UNIQUE键,那么e.time_occurred
被称为"功能依赖"甚至不会在其他符合SQL的DBMS中抛出错误。
但是,SQLite尚未实现功能依赖。在SQLite(和MySQL)的情况下,即使不在功能上依赖于GROUP BY列的列,也不会引发错误。
SQLite(和MySQL)只需从结果集中选择一个随机行来填充(在SQLite术语中)"裸列",请参阅this。