假设我们在SQLite中有以下表和查询:
id | val | 父字母 | |
---|---|---|---|
1 | 3 | 10 | a|
2 | 3 | 10 | b|
3 | 0 | 10 | c |
4 | 5 | 20 | d
SELECT/Simple SELECT Processing/旁注:聚合查询中的裸列中介绍了此行为
在查询中,未聚合且未包含在GROUP BY
子句中的列id
和letter
称为bare列
因为您使用MAX()
聚合函数,所以这两列的值:
。。。从输入行中获取值,该行还包含最小值或最大
但是,由于对于相同的parent
:,可能存在超过1行的最大val
如果两个或多个输入行具有相同的最小或最大值
这意味着对于您的样本数据,不能保证对于parent = 10
,您将在结果中获得具有id = 1
的行
您可以得到具有id = 2
的行,该行还包含最大val
假设在这种情况下,对于同一父级,可能存在超过1行具有最大val
,您希望该行具有最小id
,则可以使用窗口函数:
SELECT id, val, parent, letter
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY parent ORDER BY val DESC, id) rn
FROM tablename
)
WHERE rn = 1
或:
SELECT DISTINCT
FIRST_VALUE(id) OVER (PARTITION BY parent ORDER BY val DESC, id) id,
MAX(val) OVER (PARTITION BY parent) val,
parent,
FIRST_VALUE(letter) OVER (PARTITION BY parent ORDER BY val DESC, id) letter
FROM tablename
请参阅演示
来自官方文档
值得仔细阅读。粗体就是您要查找的内容。
聚合查询可以包含以下非聚合结果列不在GROUP BY子句中
在大多数SQL实现中,聚合查询的输出列可能仅引用GROUP BY中命名的聚合函数或列条款在聚合查询,因为每个输出行可能由两个或输入表中的多行。
SQLite不强制执行此限制。聚合查询可以是任意表达式,其中不包括在GROUP BY子句中找到。此功能有两个用途:
- 使用SQLite(但不是我们所知道的任何其他SQL实现(,如果聚合查询包含单个min((或max((函数,则输出中使用的列的值取自获得min((或max((值的行。如果两行或多行相同的min((或max((值,则将选择列值任意地从其中一行
。。。
现在,使用您的查询
SELECT id, MAX(val), parent, letter FROM table GROUP BY parent
您基本上有未聚合的id
和letter
,它们不在GROUP BY中。
这意味着为它们返回的值是来自与MAX(val)
匹配的行的值。
在你的情况下,有两个
id val parent letter
1 3 10 a
2 3 10 b
这意味着sqlite将任意(随机(返回第1行或第2行的值。所以不,你没有保证。