求SQL实现:计算TAB_PAYOUT表前13行的行差值并求和
解决SQL计算前12个列间差值求和的问题
首先纠正你原SQL里的逻辑错误:你需要的是当前行PAY减去下一行PAY,但原语句中LAG(PAY, 1, 0) - PAY计算的是上一行PAY减去当前行PAY,和需求完全相反。正确的差值计算应该用PAY - LEAD(PAY, 1) OVER (ORDER BY ID),LEAD函数才是用来获取当前行的下一行数据的。
接下来要实现“仅对前12个差值(对应前13行)求和”,可以通过给行添加序号,只保留前12行的差值(前13行里,前12行各自对应下一行,刚好产生12个有效差值)。具体实现如下:
SELECT ID, SUM(Difference) AS Total_Difference FROM ( SELECT ID, PAY, PAY - LEAD(PAY, 1) OVER (ORDER BY ID) AS Difference, ROW_NUMBER() OVER (ORDER BY ID) AS Row_Num FROM TAB_PAYOUT WHERE ID = '000000003502' ) t WHERE Row_Num <= 12 -- 只取前12行的差值,对应前13行的12个间隔 GROUP BY ID;
逻辑说明:
ROW_NUMBER() OVER (ORDER BY ID)按ID升序给每行编号,确保能精准定位到前12行。- 筛选
Row_Num <= 12,这样我们只计算第1行到第12行分别与第2行到第13行的差值,刚好是12个符合要求的差值。 - 若下一行不存在(比如第13行之后的行),
LEAD会返回NULL,但筛选条件已经排除了这些行,不会影响求和结果。
如果你的数据库支持取前N行的语法,也可以先取前13行再计算差值求和,效果一致:
-- 以Oracle为例,其他数据库可替换取前N行语法:SQL Server用TOP 13,MySQL用LIMIT 13 SELECT ID, SUM(PAY - LEAD(PAY, 1) OVER (ORDER BY ID)) AS Total_Difference FROM ( SELECT ID, PAY FROM TAB_PAYOUT WHERE ID = '000000003502' ORDER BY ID FETCH FIRST 13 ROWS ONLY ) t WHERE LEAD(PAY, 1) OVER (ORDER BY ID) IS NOT NULL -- 排除最后一行的空差值 GROUP BY ID;
内容的提问来源于stack exchange,提问作者Nash
相关产品推荐
相关产品推荐

