在 postgresql rank 的每个组上获得不同的 LIMIT

Get different LIMIT on each group on postgresql rank

要从每个组中获取 2 行,我最后可以将 ROW_NUMBER() 与条件 <= 2 一起使用,但我的问题是如果我想对每个组设置不同的限制,例如 [= 的 3 行29=] 1, 2 1 行和 3 1 行?

给出以下 table:

db=# SELECT * FROM xxx;
 id | section_id | name
----+------------+------
  1 |          1 | A
  2 |          1 | B
  3 |          1 | C
  4 |          1 | D
  5 |          2 | E
  6 |          2 | F
  7 |          3 | G
  8 |          2 | H
(8 rows)

我得到每个 section_id 的前 2 行(按 name 排序),即结果类似于:

 id | section_id | name
----+------------+------
  1 |          1 | A
  2 |          1 | B
  5 |          2 | E
  6 |          2 | F
  7 |          3 | G
(5 rows)

当前查询:

SELECT
  * 
FROM (
  SELECT
    ROW_NUMBER() OVER (PARTITION BY section_id ORDER BY name) AS r,
    t.*
  FROM
    xxx t) x
WHERE
  x.r <= 2;

只需修复您的 where 子句:

with numbered as (
  select row_number() over (partition by section_id
                                order by name) as r,
         t.*
    from xxx t
)
select *
  from numbered
 where (section_id = 1 and r <= 3)
    or (section_id = 2 and r <= 1)
    or (section_id = 3 and r <= 1);

创建一个 table 以包含部分限制,然后加入。最大的优势在于,当需要新的部分或限制更改时,维护减少到单个 table 更新并且成本非常低。参见 example

select s.section_id, s.name  
  from (select section_id, name 
             , row_number() over (partition by section_id order by name) rn
          from sections
       )  s 
  left join section_limits sl on (sl.section_id = s.section_id) 
where 
  s.rn <= coalesce(sl.limit_to,2);