SQL去重优化:如何高效获取每个账户的最新服务记录?
高效获取每个账户最新服务记录的SQL优化方案
你需要获取每个AccountNum对应最新ServiceDate的记录,现有方案要么重复书写大量字段,要么需要对所有字段分组导致维护繁琐,其实还有更简洁高效的替代方法:
1. 简化窗口函数写法(通用SQL)
去掉冗余的CTE,仅通过一次子查询实现,字段书写次数大幅减少:
SELECT AccountNum, Field2, Field3, Field4, Field5, Field6, ServiceDate FROM ( SELECT AccountNum, Field2, Field3, Field4, Field5, Field6, ServiceDate, ROW_NUMBER() OVER(PARTITION BY AccountNum ORDER BY ServiceDate DESC) AS MostRecent FROM MyTable ) AS DedupeServices WHERE MostRecent = 1
若数据库允许,子查询中也可以用*代替列名,外层仅需指定需要的字段,进一步降低重复书写成本。
2. 利用数据库特定语法(更简洁)
不同数据库提供了针对性语法,能大幅简化代码:
PostgreSQL:DISTINCT ON
直接通过DISTINCT ON指定分组字段,配合排序即可获取最新记录,字段仅需书写一次:
SELECT DISTINCT ON (AccountNum) AccountNum, Field2, Field3, Field4, Field5, Field6, ServiceDate FROM MyTable ORDER BY AccountNum, ServiceDate DESC;
SQL Server:TOP 1 WITH TIES
结合TOP 1 WITH TIES和窗口函数排序,无需子查询即可实现:
SELECT TOP 1 WITH TIES AccountNum, Field2, Field3, Field4, Field5, Field6, ServiceDate FROM MyTable ORDER BY ROW_NUMBER() OVER(PARTITION BY AccountNum ORDER BY ServiceDate DESC);
MySQL:关联子查询(兼容旧版本)
通过子查询先获取每个账户的最新服务日期,再关联原表获取完整记录,无需对所有字段分组:
SELECT t1.AccountNum, t1.Field2, t1.Field3, t1.Field4, t1.Field5, t1.Field6, t1.ServiceDate FROM MyTable t1 INNER JOIN ( SELECT AccountNum, MAX(ServiceDate) AS LatestDate FROM MyTable GROUP BY AccountNum ) t2 ON t1.AccountNum = t2.AccountNum AND t1.ServiceDate = t2.LatestDate;
注意:若同一账户存在多条相同的最新服务日期记录,此方法会返回所有对应记录,需根据需求添加额外去重逻辑。
内容的提问来源于stack exchange,提问作者user3691608
相关产品推荐
相关产品推荐

