我有一个这样的表(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。
答案 0 :(得分:1)
您可以在子查询中使用窗口函数来获取所需的内容:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="primary-navigation">
<ul id="menu-main-navigation" class="menu nav-menu">
<li id="menu-item-428" class="main-nav-item-1">
<a href="https://link-1.com">Link-1</a></li>
<li id="menu-item-344" class="main-nav-item-2">
<a href="https://link-2.com">Link-2</a></li>
<li id="menu-item-228" class="main-nav-item-3">
<a href="https://link-3.com">Link-3</a></li>
<li class="underline-border"></li>
</ul>
</div>
row_number()提供了该组内的一个序列(使用PARTITION BY)。
答案 1 :(得分:0)
@Nick的答案是我要发布的内容,但是要说一件事,如果您想跳过重复项,可以使用dense_rank函数:
SELECT pk, grp, attr, val FROM (
SELECT
*,
DENSE_RANK() OVER (PARTITION BY grp ORDER BY val DESC) AS seqnum
FROM
mytable
) t WHERE seqnum = 2;