根据PostgreSQL中的条件在组中选择一行

根据PostgreSQL中的条件在组中选择一行,sql,postgresql,group-by,Sql,Postgresql,Group By,我有一张这样的表格(tbl): 我想从每个组中选择一行,特别是每个组的最大值val 我可以轻松地选择grp和val: SELECT grp, MAX(val) FROM tbl GROUP BY grp 生成此表(tbl2): 但是,我想要这个表: +----+-----+------+-----+ | pk | grp | attr | val | +----+-----+------+-----+ | 1 | 0 | foha | 56 | | 3 | 1 | faso |

我有一张这样的表格(
tbl
):

我想从每个组中选择一行,特别是每个组的最大值
val

我可以轻松地选择
grp
val

SELECT grp, MAX(val)
FROM tbl
GROUP BY grp
生成此表(
tbl2
):

但是,我想要这个表:

+----+-----+------+-----+
| pk | grp | attr | val |
+----+-----+------+-----+
|  1 |   0 | foha |  56 |
|  3 |   1 | faso |  11 |
|  5 |   2 | bnda |  12 |
+----+-----+------+-----+
由于
(grp,val)
构成了一个键,我可以在
grp
val
的相同
tbl2
上加入
tbl

然而,我想知道是否还有其他解决方案:在我的现实世界中,
tbl
是一个非常复杂和繁重的派生表,我的设计限制是不能使用临时表。是否有办法根据
val
对每个组内的行进行排序,然后为每个组获取第一条记录


我使用的是PostgreSQL 10,但标准SQL解决方案是最好的。

在Postgres中,最好的方法是
上进行区分:

SELECT DISTINCT ON (t.grp) t.*
FROM tbl
ORDER BY grp, val DESC;

特别是,这可以利用
(grp,val desc)

上的索引。在Postgres中,最好的方法是
上进行区分:

SELECT DISTINCT ON (t.grp) t.*
FROM tbl
ORDER BY grp, val DESC;

特别是,这可以利用
(grp,val desc)

上的索引进行集成:PosgreSQL文档特别提到“SELECT DISTINCT on(表达式[,…])只保留给定表达式计算为相等的每组行的第一行。它们[…]使用与ORDER BY[…]相同的规则进行解释。请注意,每个集合的“第一行”是不可预测的,除非使用ORDER BY来确保所需的行出现在第一行。”。这将使您的
解决方案上清晰可见。需要注意的是,对于
独特的
条款,在订购时没有做出相同的保证!集成:PosgreSQL文档特别提到“SELECT DISTINCT ON(表达式[,…])只保留每组行中给定表达式计算结果相等的第一行。它们[…]使用与ORDER BY[…]相同的规则进行解释。请注意,“第一行“除非使用ORDER BY来确保所需行首先出现,否则每个集合的排序都是不可预测的。”。这会使您的
DISTINCT ON
解决方案正确无误。应该注意的是,对于
DISTINCT
子句,在排序上不会做出相同的保证!
SELECT DISTINCT ON (t.grp) t.*
FROM tbl
ORDER BY grp, val DESC;