SQLSERVER 2012計算上一條,下一條資料的函式
阿新 • • 發佈:2022-04-28
實際需求很普遍,比如求銷售資料的每天與頭一天的銷售增長量。這裡用一個汽車行駛資料來做例子:
先初始化資料:
CREATE TABLE [dbo].[CarData]( [CarID] [int] NULL, [Mileage] [int] NULL, [M_year] [int] NULL, [M_Month] [int] NULL, [M_Day] [int] NULL ) ON [PRIMARY] GO INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 10, 2015, 1, 1) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 15, 2015, 1, 2) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 15, 2015, 1, 5) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 20, 2015, 1, 6) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 26, 2015, 1, 9) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 30, 2015, 1, 10) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (1, 35, 2015, 1, 11) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (2, 20, 2015, 1, 5) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (2, 22, 2015, 1, 8) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (2, 40, 2015, 1, 10) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (2, 45, 2015, 1, 11) INSERT [dbo].[CarData] ([CarID], [Mileage], [M_year], [M_Month], [M_Day]) VALUES (3, 50, 2015, 1, 11)
然後,使用下面的SQL來統計:
WITH ONE AS( SELECT ROW_NUMBER() OVER(PARTITION BY CarId ORDER BY CarId, M_Year, M_Month, M_Day) AS NodeId ,C.CarId ,C.Mileage ,C.M_Year ,C.M_Month ,C.M_Day FROM dbo.CarData AS C ) SELECT * ,COALESCE(One.Mileage - LAG(One.Mileage) over(PARTITION BY CarId order by One.NodeId),0) AS '增量' FROM ONE
這裡使用LAG函式來計算。
注意,這個查詢只有在SQLSERVER 2012以上才支援,2008不支援,所以採用下面的方法實現:
WITH TWO AS( SELECT ROW_NUMBER() OVER(PARTITION BY CarId ORDER BY CarId, M_Year, M_Month, M_Day) AS NodeId ,C.CarId ,C.Mileage ,C.M_Year ,C.M_Month ,C.M_Day FROM [dbo].[CarData] AS C ) SELECT A.* , A.Mileage - COALESCE(B.NextMileage, 0) AS '增量' FROM TWO AS A OUTER APPLY (SELECT Mileage AS NextMileage FROM TWO AS B WHERE B.NodeId = A.NodeId - 1 AND B.CarId = A.CarId ) AS B;
執行查詢,將得到下面的結果:
1 1 10 2015 1 1 10
2 1 15 2015 1 2 5
3 1 15 2015 1 5 0
4 1 20 2015 1 6 5
5 1 26 2015 1 9 6
6 1 30 2015 1 10 4
7 1 35 2015 1 11 5
1 2 20 2015 1 5 20
2 2 22 2015 1 8 2
3 2 40 2015 1 10 18
4 2 45 2015 1 11 5
1 3 50 2015 1 11 50
感謝 SOD開發技術群(PWMIS開發框架-SOD會員群 43109929)朋友提供的程式。