在 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
丢弃排名> 2的项目。但是我需要的是这样的结果
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
没有丢弃的行。
编辑: 为了更准确地说明我需要的逻辑:
- 给我得分最高的行
- 具有相同颜色和最高分的下一行
- 剩余项目中得分最高的项目
- 与 2. 相同,但用于 3.
的行 ...
继续下去,只要能找到相同颜色的对,剩下的按分数降序排列。
可以找到测试表的导入语句here . 感谢您的帮助。
最佳答案
可以使用两个嵌套的窗口函数来完成
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
是组大小的参数。
关于Postgresql:使用窗口函数对组大小进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16167434/