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

标签 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

我可以通过以下查询使用窗口函数根据颜色进行分组

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

没有丢弃的行。

编辑: 为了更准确地说明我需要的逻辑:

  1. 给我得分最高的行
  2. 具有相同颜色和最高分的下一行
  3. 剩余项目中得分最高的项目
  4. 与 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/

相关文章:

php - PostgreSQL 多条件语句

sql - 均匀间隔的多个平均值

sql - 使用另一行数据的 SELECT 查询

performance - PostgreSQL 的 Multi-Tenancy 应用程序模式

postgresql - 我们可以使用 PostgreSQL ltree 表示 DAG(有向无环图)吗?

php - 查询对象数组(带 JSONB 的 Postgres,Laravel 5)

sql - 将一列中具有相同值的连续行减少为单行

postgresql - Postgres缓存(shared_buffers)数据是按照索引排序的吗?

sql - 如何在 postgres 中使用 "Group By"作为日期间隔

sql - 选择运动员在过去 3 项比赛中未获得第一名的成绩