我有一个这样的表(tbl
):
+----+-----+------+-----+
| pk | grp | attr | val |
+----+-----+------+-----+
| 0 | 0 | ohif | 4 |
| 1 | 0 | foha | 56 |
| 2 | 0 | slns | 2 |
| 3 | 1 | faso | 11 |
| 4 | 1 | tepj | 4 |
| 5 | 2 | bnda | 12 |
| 6 | 2 | ojdf | 9 |
| 7 | 2 | anaw | 1 |
+----+-----+------+-----+
我想从每组中选择一行,尤其是每组最多val
的行。
我可以轻松选择grp
和val
:
SELECT grp, MAX(val)
FROM tbl
GROUP BY grp
产生此表(tbl2
):
+-----+-----+
| grp | val |
+-----+-----+
| 0 | 56 |
| 1 | 11 |
| 2 | 12 |
+-----+-----+
但是,我想要这张桌子:
+----+-----+------+-----+
| pk | grp | attr | val |
+----+-----+------+-----+
| 1 | 0 | foha | 56 |
| 3 | 1 | faso | 11 |
| 5 | 2 | bnda | 12 |
+----+-----+------+-----+
由于(grp, val)
构成了密钥,因此我可以将tbl2
与tbl
留在同一grp
和val
上。
但是,我想知道是否还有其他解决方案:在我的实际情况下,tbl
是一个非常复杂且繁重的派生表,并且我的设计约束是无法使用临时表。有什么方法可以根据val
对每个组中的行进行排序,然后为每个组获取第一条记录?
我使用的是PostgreSQL 10,但是最好的标准SQL解决方案。
答案 0 :(得分:2)
在Postgres中,最好的方法是distinct on
:
SELECT DISTINCT ON (t.grp) t.*
FROM tbl
ORDER BY grp, val DESC;
尤其是,这可以利用(grp, val desc)
上的索引。