工作笔记 - PG分组极值

概述

笔者在工作的过程中,遇到一个比较典型的问题,就是需要查找分组记录中的某个极值所对应的记录。

一个经典的场景就是学生科目成绩表。分组的依据是科目。想要查询各个科目成绩最好的学生记录(假设没有并列排名)。

比较传统的方式是分组聚合(Group By) ,查到分组中的最高分,然后倒查学生记录。

还有一种方式是使用窗口函数( Rank() over ... ),找到记录在窗口中对应的排序,然后取各个窗口序号为一的那条记录。

笔者觉得这两种方式对于这个简单的需求而言,都过于繁琐。 经过和AI的讨论,发现了一种看起来比较简洁的技术方案。觉得有点意思,处理的思路也很有启发,遂著文记录和分享之。

技术方案

简单而言,这个技术方案的核心SQL是:

"Distinct ON(field)"

它可以处理重复字段值,也就是记录分组,并保留记录其他字段的值。

下面是完整的示例:

sql 复制代码
SELECT DISTINCT ON (course) stuid, course, score, examtime 
FROM scores 
ORDER BY course, score desc

// 还可以写成

SELECT DISTINCT ON (course) * FROM scores 
ORDER BY course, score desc

假设这里分组的依据是科目 course, 这个查询就可以查出分组中,按照分数倒排第一记录,当然包括学生的ID和其他其他信息。最后再对course进行汇总,就查询出所有科目的第一名学生的信息了。

简单总结一下用法:

  • distinct on () 用于指定分组的依据,所谓分组,就是字段值相同的记录的集合,它使用重复值来进行处理
  • 后面可选要提取的字段,也可以是 *
  • 关键是排序方式,因为这里的场景比较简单,就是取排序中的极值,所以先按分组排序,然后按值排序

这个查询笔者是在Postgres中调试和通过的,其他SQL系统的支持和实现情况未知。

小结

本文探讨和记录了一种不使用聚合查询和窗口函数来查询分组极值记录的一种方式。已经在笔者的一个应用中使用,觉得值得分享和探讨。

相关推荐
城管不管7 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
倔强的石头1068 小时前
向量数据库从相似度检索走向融合数据底座
数据库
AI绘画哇哒哒8 小时前
【建议收藏!】35岁后端血泪忠告,这3类人别硬转Agent(过来人亲述)
java·人工智能·后端·ai·程序员·大模型·agent
唐青枫9 小时前
一个值多种形态:Zig union、Tagged Union 与内存布局实战
后端
今天AI了吗9 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·数据库·人工智能·python·sql·深度学习·机器学习
卷无止境9 小时前
Windows 上丝滑开发 Python,并稳定构建 Docker 镜像
后端·python·docker
Nturmoils9 小时前
备份完不算完,先还原到临时库验一遍
后端
Csvn10 小时前
📊 SQL 入门 Day 22:视图与物化视图
后端·sql
Csvn10 小时前
🐍 Day 4: Python 控制流 — 条件、循环与推导式的艺术
后端·python
lilian23310 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos