当前位置: 首页 > 面试题库 >

在SQLite GROUP BY查询的SELECT列表中包括额外的列是否安全?

鲜于阳成
2023-03-14
问题内容

我有一个简单的SQLite表,称为“消息”:

sequence INTEGER PRIMARY KEY
type TEXT
content TEXT

我想获取每种类型的最后一条消息的内容(由其顺序确定)。令我惊讶的是,以下简单查询有效:

SELECT MAX(sequence), type, content
FROM message
GROUP BY type

令人惊讶,因为我知道MSSQL或Postgres会拒绝在SELECT列表中包括不属于GROUP BY子句或聚合函数一部分的列,因此我必须进行联接,如下所示:

SELECT m.sequence, m.type, m.content
FROM
(
    SELECT MAX(sequence) as sequence, type
    FROM message
    GROUP BY type
) g
JOIN message m
ON g.sequence = m.message_sequence

我的问题是:在SQLite中使用第一种更简单的查询形式是否安全?从直觉上讲,它选择的是与“ MAX(sequence)”值匹配的“
content”值,但是文档似乎根本没有讨论这一点。当然,如果序列不是唯一的,那么结果将是不确定的。但是,如果序列是唯一的,例如在我的情况下,这是可以保证的,还是只是幸运的实现细节会随时更改?


问题答案:

如果多余的列在 功能上取决于 您分组的列,则可以“安全”地使用这些查询,即不会导致歧义的结果:

SELECT c.parent_id, COUNT(*), p.any_column
FROM child_table c 
JOIN parent_table p USING (parent_id)
GROUP BY c.parent_id;

上面的示例将在SQLite中工作,并产生明确的结果,因为p.any_column每个组不可能有多个值。但是,此查询严格违反SQL标准,并且大多数品牌的RDBMS都会引发错误。

但是,编写产生歧义结果的查询太容易了。当命名每个组具有多个值的列时,您将无法控制在结果集中返回哪个值。

实际上,MySQL从物理存储第一 行返回该值,而SQLite从 最后
一行返回该值。但这完全依赖于实现且不可靠。如果任一软件的下一版本更改了内部结构,则升级后您可能会获得不同的查询结果。因此,最好不要依赖此行为。

对于您的示例,wherecontent应该“直观地”具有sequenceMAX为行中的值。但这真的很直观吗?考虑以下其他情况:

SELECT MAX(sequence), MIN(sequence), type, content
FROM message
GROUP BY type

那么,现在哪一行提供了价值content?行sequence是MAX,还是行sequenceMIN?

如果您使用非唯一列(例如date),并且有多行具有相同的MAX值date,但具有不同的值content怎么办?

SELECT MAX(date), type, content
FROM message
GROUP BY type

其他聚合函数(例如AVG()或)SUM()呢?汇总的值可能对应于表中没有单独的行。那么,现在应该为哪一行提供值content

SELECT AVG(sequence), type, content
FROM message
GROUP BY type


 类似资料:
  • 在ApacheFelixOSGi框架中,配置文件提供了在Felix生态系统中包含其他系统包的选项。Felix配置中的行如下所示: 我将当前的OSGi框架从Felix切换到EclipseEquinox,我发现我的一个捆绑包依赖于包,但在Equinox的(模糊的)配置文档中找不到任何与Felix中的设置等效的东西。有人知道Equinox的方式包括这个额外的包吗? 如果您正在查看我在上面共享的链接(到E

  • 问题内容: 我有两个列表,一个包含 相册,文件对的 列表,另一个仅包含有关一张照片的信息- 相册 (位置0)和 文件 (位置1) 如何查看 照片 列表是否在 照片 列表中?就像字符串一样。 相册 , 文件的 位置无关紧要,因为不会有任何 文件 等于 相册 。 问题答案: 同样喜欢字符串。不仅如此,也是 如此 。也适用于列表中的列表: 对列表的成员资格测试仅迭代列表,并对每个元素使用相等性测试以查看

  • 问题内容: 这是我正在尝试做的事情和获得的最简单的工作示例: 我有一个查询,如下所示: 注意: tran_party.team_id_redirect 是引用 team.team_id 的外键。 电流输出: 预期产量: 我希望列中的重复项仅被选择一次,如下所示: 我试过的 我写了一个内联视图,而不是直接从中选择,而是从tran_party中选择不同的值,如下所示: 尽管这确实给了我预期的输出,但是

  • 问题内容: 我有这样的df: 以及物品清单: 我的目标是从中获取至少包含2个元素的所有行。 我想出了以下解决方案: 这给了我我想要的,但是就可伸缩性而言,它可能不是最佳的解决方案。是否有任何“向量化”解决方案?谢谢 问题答案: 我会建立一个Series列表,然后应用vectorized : 它给出了预期的结果:

  • 问题内容: 假设我们有一个 类别-项目 一对多 关系。我想这样做 假设我们有一个Hibernate POJO“类类别”。 我的第一个问题是我真的无法弄清楚从该查询中我得到List 对象对吗?以及如何访问“ itemCount”?因为没有 Category.getItemCount() 其次,如何编写条件查询? 谢谢 问题答案: 似乎这是我正在寻找的答案(进入POJO):