Oracle转SQL Server:如何替换KEEP(DENSE_RANK FIRST ORDER BY...)语法?
替代Oracle KEEP语法的SQL Server写法
首先明确原Oracle语句的功能:按no分区,获取每个分区中ap_year的最小值(由于KEEP (DENSE_RANK FIRST ORDER BY ap_year)会保留分区内ap_year最小的所有行,再取这些行的ap_year最小值,本质就是分区内的最小ap_year)。
针对SQL Server,有以下几种等价实现方式:
1. 直接使用MIN窗口函数(最简洁)
这是和原语句逻辑完全等价的写法,直接通过MIN()窗口函数计算每个分区的最小ap_year:
MIN(ap_year) OVER (PARTITION BY no) AS first_ap_year
2. 使用FIRST_VALUE窗口函数
如果你的场景需要扩展(比如要获取对应最小ap_year的其他列值),可以用FIRST_VALUE(),它会返回分区内按指定排序后的第一个值:
FIRST_VALUE(ap_year) OVER ( PARTITION BY no ORDER BY ap_year ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS first_ap_year
注:添加ROWS BETWEEN子句是确保窗口包含分区内所有行,避免默认窗口范围导致的结果偏差;如果分区内有多个相同的最小ap_year,FIRST_VALUE会返回排序后第一个出现的值,和原Oracle语句中MIN()取的结果一致。
3. 使用ROW_NUMBER()筛选(适用于单条结果场景)
如果只需要每个no对应的最小ap_year单行记录,可以用CTE结合ROW_NUMBER():
WITH ranked_data AS ( SELECT no, ap_year, ROW_NUMBER() OVER (PARTITION BY no ORDER BY ap_year) AS row_rank FROM your_table ) SELECT no, ap_year AS first_ap_year FROM ranked_data WHERE row_rank = 1;
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

