PostgreSQL:使用窗口函数对组大小进行分组

Mar*_*ake 5 postgresql window-functions

在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
Run Code Online (Sandbox Code Playgroud)

我可以使用以下查询通过基于窗口功能的颜色进行分组

SELECT * FROM (
    SELECT id, color, score, rank()
    OVER (PARTITION BY color ORDER BY score DESC)
    FROM grouping_test
) AS foo WHERE rank <= 2;
Run Code Online (Sandbox Code Playgroud)

结果

  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
Run Code Online (Sandbox Code Playgroud)

它会丢弃等级大于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
Run Code Online (Sandbox Code Playgroud)

没有丢弃的行。

编辑: 要更精确地了解我需要的逻辑:

  1. 让我获得最高分的行
  2. 具有相同颜色和最高分数的下一行
  3. 其余项目中得分最高的项目
  4. 与2.相同,但对于从3开始的行

只要找到具有相同颜色的对,就继续,然后按降序排列剩下的东西。

可在此处找到测试表的导入语句。谢谢你的帮助。

Mar*_*ake 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;
Run Code Online (Sandbox Code Playgroud)

2组大小的参数。