在Postgresql中是否有办法编写一个查询,该查询根据具有限制的列对行进行分组而不丢弃其他行。
假设我有一个包含三列id, color, score
的表格,其中包含以下行
1 red 10.0
2 red 7.0
3 red 3.0
4 blue 5.0
5 green 4.0
6 blue 2.0
7 blue 1.0
我可以使用带有以下查询的窗口函数获得基于颜色的分组
SELECT * FROM (
SELECT id, color, score, rank()
OVER (PARTITION BY color ORDER BY score DESC)
FROM grouping_test
) AS foo WHERE rank <= 2;
结果
id | color | score | rank
----+-------+-------+------
4 | blue | 5.0 | 1
6 | blue | 2.0 | 2
5 | green | 4.0 | 1
1 | red | 10.0 | 1
2 | red | 7.0 | 2
丢弃带有排名&gt;的项目但是,我需要的是像
这样的结果1 red 10.0
2 red 7.0
4 blue 5.0
6 blue 2.0
5 green 4.0
3 red 3.0
7 blue 1.0
没有丢弃的行。
修改 更准确地说我需要的逻辑:
只要可以找到具有相同颜色的对,然后按降序分数排序。
可以找到测试表的import语句here。 谢谢你的帮助。
答案 0 :(得分:3)
可以使用两个嵌套的窗口函数
来完成SELECT
id
FROM (
SELECT
id,
color,
score,
((rank() OVER color_window) - 1) / 2 AS rank_window_id
FROM grouping_test
WINDOW color_window AS (PARTITION BY color ORDER BY score DESC)
) as foo
WINDOW rank_window AS (PARTITION BY (color, rank_window_id))
ORDER BY
(max(score) OVER rank_window) DESC,
color;
2
是组大小的参数。
答案 1 :(得分:1)
您可以ORDER BY (rank <= 2) DESC
获取排名&lt; = 2的行高于其他所有行:
SELECT id,color,score FROM (
SELECT id, color, score, rank()
OVER (PARTITION BY color ORDER BY score DESC),
max(score) OVER (PARTITION BY color) mx
FROM grouping_test
) AS foo
ORDER BY
(rank <= 2) DESC,
CASE WHEN rank<=2 THEN mx ELSE NULL END DESC,
id;