PostgreSQL 中的分组限制:显示每个组的前 N 行,但仅当这些行中的第一行等于特定数据时
Posted
技术标签:
【中文标题】PostgreSQL 中的分组限制:显示每个组的前 N 行,但仅当这些行中的第一行等于特定数据时【英文标题】:Grouped LIMIT in PostgreSQL: show the first N rows for each group, BUT only if the first of those row equals specific data 【发布时间】:2021-02-27 12:27:05 【问题描述】:考虑下表:
SELECT * FROM report_raw_data;
ts | d_stamp | id_mod | value
-----------+------------+--------+------
1605450647 | 2020-11-15 | 1 | 60
1605464634 | 2020-11-15 | 2 | 54
1605382126 | 2020-11-14 | 1 | 40
1605362085 | 2020-11-14 | 3 | 33
1605355089 | 2020-11-13 | 1 | 60
1605202153 | 2020-11-12 | 2 | 30
我需要的是获取按每个 id_mod 的 ts 排序的前两行,但前提是 d_stamp 是当前日期(在本例中为 2020-11-15)。
到目前为止,我已经设法让每个 id_mod 的前两行按 ts 排序,但我很难找到唯一的当前日期 2020-11-15。
这是我的错误结果尝试:
SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY id_mod ORDER BY ts DESC) AS r,t.* FROM
report_raw_data t) x WHERE x.r <= 2;
ts | d_stamp | id_mod | value
-----------+------------+--------+------
1605450647 | 2020-11-15 | 1 | 60
1605382126 | 2020-11-14 | 1 | 40
1605464634 | 2020-11-15 | 2 | 54
1605202153 | 2020-11-12 | 2 | 30
1605362085 | 2020-11-14 | 3 | 33
如果我在查询中使用 WHERE = '2020-11-15',我最终将只获得我需要的那些记录(因此没有第二行)。
这是我想要得到的(忽略 id_mod 编号 3),因为它是第一行不是从 2020-11-15 开始的:
ts | d_stamp | id_mod | value
-----------+------------+--------+------
1605450647 | 2020-11-15 | 1 | 60
1605382126 | 2020-11-14 | 1 | 40
1605464634 | 2020-11-15 | 2 | 54
1605202153 | 2020-11-12 | 2 | 30
还有一点需要注意:我需要能够在查询中使用 LIMIT 和 OFFSET 才能对前端的结果进行分页。
【问题讨论】:
【参考方案1】:从您当前的查询开始,一个简单的方法是在子查询中使用一个窗口MAX()
来根据id_mod
恢复最新的ts
。然后,您可以将其用于外部查询中的其他过滤。
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY id_mod ORDER BY ts DESC) AS rn,
MAX(ts) OVER(PARTITION BY id_mod) max_ts
FROM report_raw_data t
) x
WHERE rn <= 2 and max_ts = current_date;
【讨论】:
@xyz83242:你不接受这个答案有什么原因吗?【参考方案2】:假设您没有未来的数据,我建议:
SELECT rdr.*
FROM (SELECT rdr.*,
ROW_NUMBER() OVER (PARTITION BY id_mod ORDER BY ts DESC) AS seqnum
FROM report_raw_data rdr
WHERE d_stamp = current_date
) rdr
WHERE seqnum <= 2;
基于子查询中的时间进行过滤应该会显着提高性能。为了获得最佳性能,您需要在(d_stamp, id_mod, ts desc)
上建立索引。
【讨论】:
以上是关于PostgreSQL 中的分组限制:显示每个组的前 N 行,但仅当这些行中的第一行等于特定数据时的主要内容,如果未能解决你的问题,请参考以下文章