是否对 GROUP BY 查询中的非聚合列有保证?

Jon*_*nas 5 sqlite group-by

假设我们在 SQLite 中有下表和查询:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
ID瓦尔家长
1310A
2310
3010C
4520d
\n
\n
SELECT id, MAX(val), parent, letter FROM table GROUP BY parent\n
Run Code Online (Sandbox Code Playgroud)\n

的价值有任何保证吗id?在 MySQL 中甚至有一种模式禁止选择非聚合值。如果没有这样的保证,是否有可能以某种方式获得每行parent

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
ID最大值(值)家长
1\xe2\x80\xa0310A
4520d
\n
\n

letter\xe2\x80\xa0 或 2(只要来自同一行就没关系)

\n

for*_*pas 1

此行为在 S ELECT/简单选择处理/旁注:聚合查询中的裸列中进行了介绍。

在查询中,未聚合且未包含在子句中的列id和称为列。 因为您使用聚合函数,所以这两列的值:letterGROUP BY
MAX()

...从还包含最小值或最大值的输入行中获取值

但是,由于可能存在超过 1 行且其最大值val相同parent

如果两个或多个输入行具有相同的最小值或最大值,则仍然存在歧义

这意味着对于您的示例数据,不能保证您将获得结果中的parent = 10行。您可能会得到也包含最大值的 行。id = 1
id = 2val

假设在这种情况下,对于同一个父级,可能存在超过 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
Run Code Online (Sandbox Code Playgroud)

或者:

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 
Run Code Online (Sandbox Code Playgroud)

请参阅演示