为什么SQLite3不会产生错误

时间:2017-04-06 10:42:46

标签: python sqlite

我对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。

3 个答案:

答案 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_idevents中的主键,那么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