SQL分组后取第一条记录

上周,我在处理业务数据时,遇到了一个头疼的问题:需要从每个小组中找出特定记录。
这让我想起了三种常用的方法。

第一种是生成分组并排序。
我在2 02 3 年3 月的一次项目中,用这个方法筛选了每个员工的最高英语成绩。
先对数据按成绩排序,然后选取每个组的最高分。
这方法的好处是灵活,但缺点是效率不高,因为要进行两次查询。

第二种是利用左连接。
我之前在一家互联网公司用这个方法处理过数值和日期字段。
它直接给出了每个员工的最高成绩,但局限性大,不适用于所有类型的数据。

最后一种是先排序再分组。
我在2 02 3 年5 月的一个项目中尝试过,但发现它会牺牲数据的原始顺序,操作也复杂,所以并不推荐。

不过,我刚刚想到另一件事,就是有时候根据具体情况,可能需要结合这三种方法,以达到最佳效果。
你看着办吧。

sql按字段分组,并且找出每组的第一条数据

说白了,这个问题是关于如何从SQL Server和Oracle数据库中查询特定星期和字母的数据。
其实很简单,两种数据库的查询逻辑略有不同。

先说最重要的,SQL Server中你可以这样写: sql SELECT 星期, 字母 FROM ( SELECT rank() OVER (PARTITION BY 星期 ORDER BY 字母 DESC) AS id, FROM 表 ) t1 WHERE id = 1 ;
另外一点,Oracle中稍微有点不同,你需要用ROW_NUMBER()替代rank(): sql SELECT 星期, 字母 FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY 星期 ORDER BY 字母 DESC) AS id, FROM 表 ) t1 WHERE id = 1 ;
还有个细节挺关键的,Oracle的ROW_NUMBER()和SQL Server的rank()在处理并列排名时表现不同。
我一开始以为它们是一样的,但后来发现Oracle会为并列的记录分配不同的ROW_NUMBER()值,而rank()会跳过后续的排名。

等等,还有个事,如果你只是想获取每个星期的最大字母值,那么两种数据库的查询会更简单: sql SQL Server: SELECT 星期, MAX(字母) AS 最大字母 FROM 表 GROUP BY 星期;
Oracle: SELECT 星期, MAX(字母) AS 最大字母 FROM 表 GROUP BY 星期;
说实话挺坑的,有时候人们没注意GROUP BY和MAX函数的用法,觉得可以直接在SELECT中用MAX,其实不是这样。

我觉得值得试试,如果你遇到类似的查询需求,可以按照这个思路来操作。