PostgreSQL数据库特定查询需求:np范围下itt极值关联查询
PostgreSQL查询:提取itt局部最小值并关联后续局部最大值
核心思路
基于时间字段at的顺序,通过窗口函数识别局部极值,再将每个局部最小值与后续第一个局部最大值关联,同时保留最小值对应的完整行数据。
实现代码
WITH filtered_data AS ( -- 筛选np在20-400之间的数据,并按时间排序 SELECT * FROM your_table_name WHERE np > 20 AND np < 400 ORDER BY at ), extrema_markers AS ( -- 标记每行是否为局部最小值/最大值 SELECT *, CASE -- 首行:仅小于下一行则为局部最小 WHEN LAG(itt) OVER (ORDER BY at) IS NULL AND itt < LEAD(itt) OVER (ORDER BY at) THEN TRUE -- 末行:仅小于上一行则为局部最小 WHEN LEAD(itt) OVER (ORDER BY at) IS NULL AND itt < LAG(itt) OVER (ORDER BY at) THEN TRUE -- 中间行:小于前后两行则为局部最小 WHEN itt < LAG(itt) OVER (ORDER BY at) AND itt < LEAD(itt) OVER (ORDER BY at) THEN TRUE ELSE FALSE END AS is_local_min, CASE -- 首行:仅大于下一行则为局部最大 WHEN LAG(itt) OVER (ORDER BY at) IS NULL AND itt > LEAD(itt) OVER (ORDER BY at) THEN TRUE -- 末行:仅大于上一行则为局部最大 WHEN LEAD(itt) OVER (ORDER BY at) IS NULL AND itt > LAG(itt) OVER (ORDER BY at) THEN TRUE -- 中间行:大于前后两行则为局部最大 WHEN itt > LAG(itt) OVER (ORDER BY at) AND itt > LEAD(itt) OVER (ORDER BY at) THEN TRUE ELSE FALSE END AS is_local_max FROM filtered_data ), local_max_list AS ( -- 提取所有局部最大值的时间和对应itt值 SELECT at AS max_timestamp, itt AS subsequent_max_itt FROM extrema_markers WHERE is_local_max ) -- 关联局部最小值与后续第一个局部最大值 SELECT em.*, lml.subsequent_max_itt FROM extrema_markers em LEFT JOIN LATERAL ( SELECT subsequent_max_itt FROM local_max_list lml WHERE lml.max_timestamp > em.at ORDER BY lml.max_timestamp LIMIT 1 ) lml ON TRUE WHERE em.is_local_min;
关键说明
- 窗口函数用法:
LAG和LEAD分别获取当前行的前一行、后一行itt值,以此判断是否为局部极值。 - 边界行处理:首尾行仅需与唯一相邻行比较即可判定是否为极值。
- 关联后续最大值:使用
LATERAL JOIN为每个局部最小值找到时间上最早的后续局部最大值,左连接确保即使没有后续最大值,最小值行仍会被保留。
性能优化建议
针对600万行的大表,需添加以下索引提升查询效率:
-- 加速np范围过滤和时间排序 CREATE INDEX idx_table_np_at ON your_table_name(np, at); -- 单独加速时间排序(若已有复合索引可忽略) CREATE INDEX idx_table_at ON your_table_name(at);
内容的提问来源于stack exchange,提问作者Eitan Spiegel
相关产品推荐
相关产品推荐

