T-SQL中真的没有First/Last聚合函数吗?求最优替代方案
为什么T-SQL没有First/Last聚合函数?求最优替代方案
我一直疑惑为什么T-SQL里没有First/Last聚合函数?这是我工作中频繁需要实现的功能,试过LAST_VALUE()、FIRST_VALUE()窗口函数、子查询、WITH语句(CTE)等多种替代方案,但还是想找到最优解法。
示例数据与现有替代方案
tbl表结构及数据如下:
| id | group | order | fact |
|---|---|---|---|
| 01 | 1 | 1 | 101 |
| 02 | 1 | 2 | 105 |
| 03 | 2 | 1 | 103 |
| ... | ... | ... | ... |
方案一:使用LAST_VALUE窗口函数
SELECT DISTINCT [group] ,LAST_VALUE(fact) OVER(PARTITION BY [group] ORDER BY [order] RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS LastFact from tbl
该方案可正常运行,但如果需要包含id或order列(通常为datetime类型),则需要将结果表与原表关联。
方案二:使用CTE
WITH cte AS ( SELECT [group] ,MAX([order]) AS MaxOrder FROM tbl GROUP BY [group] ) SELECT t.id ,t.[group] ,t.[order] ,t.fact FROM tbl t JOIN cte c ON t.[group] = c.[group] AND t.[order] = c.MaxOrder WHERE c.[group] IS NOT NULL and c.MaxOrder IS NOT NULL
该方案可行,但在包含大量CTE的复杂查询中,运行时长会显著增加。
方案三:使用子查询
SELECT t.ID ,t.[group] ,t.[order] ,t.fact FROM tbl t INNER JOIN ( SELECT [group] ,MAX([order]) as LastOrder FROM tbl GROUP BY [group]) c ON t.[group] = c.[group] and t.[order] = c.LastOrder
该方案可行,但当查询中包含多个此类子查询时,可读性会急剧下降。另外曾听讲师建议尽量避免子查询,这个说法是否准确?
还有一种方案是使用嵌套SELECT语句,但通常会导致运行时长过长,实现也复杂,甚至没法写出可用的示例。
请问还有其他更优的替代方案吗?
内容的提问来源于stack exchange,提问作者Glen Hamblin
相关产品推荐
相关产品推荐

