postgresql - 选择组内具有第二高值的行
问题描述
我有一个这样的表(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
每组第二高的那一行。
即,我想要这张桌子:
+----+-----+------+-----+
| pk | grp | attr | val |
+----+-----+------+-----+
| 1 | 0 | ohif | 4 |
| 3 | 1 | tepj | 4 |
| 5 | 2 | ojdf | 9 |
+----+-----+------+-----+
这是我想出的解决方案:
SELECT DISTINCT ON (grp)
pk,
(
SELECT innertbl.grp
FROM tbl AS innertbl
WHERE innertbl.grp = tbl.grp
ORDER BY innertbl.val DESC
LIMIT 1 OFFSET 1
) AS grp,
(
SELECT innertbl.attr
FROM tbl AS innertbl
WHERE innertbl.grp = tbl.grp
ORDER BY innertbl.val DESC
LIMIT 1 OFFSET 1
) AS attr,
(
SELECT innertbl.val
FROM tbl AS innertbl
WHERE innertbl.grp = tbl.grp
ORDER BY innertbl.val DESC
LIMIT 1 OFFSET 1
) AS val
FROM tbl
但是,这是低效的,因为它需要为每个组选择每个列的子查询。
我在 Postgres 10 上。
解决方案
您可以在子查询中使用窗口函数来获得所需的内容:
SELECT
pk, grp, attr, val
FROM (
SELECT
pk, grp, attr, val,
row_number() OVER(PARTITION BY grp ORDER BY val DESC) AS seq
FROM
tbl
) data
WHERE
seq = 2
row_number() 提供组内的序列(使用 PARTITION BY)。
推荐阅读
- swift - Swift --- 在 for in 循环中将 Char 转换为 Int
- r - R CMD CHECK --as-cran 在 OS X Catalina 上失败
- node.js - 关于 node.js 问题的 HTTPS
- reactjs - RDU - Axios、Express 和 Multer
- python - 具有多个用户类和 SSO 的 Flask 登录
- python - 检测pygame中矩形列表之间冲突的最有效方法?
- javascript - 我想了解为什么教授在一种语法中使用两个参数括号
- google-cloud-dataflow - 谷歌数据流中的 Pardo 函数不产生任何输出
- reactjs - 在 Firebase Firestore React 中添加数据
- node.js - 在 Node.js 应用程序中,如何在 EC2 上调用程序并等待 csv 输出