SQL:使用上一列进行当前列计算

时间:2016-07-28 19:46:57

标签: sql

假设我有一张这样的表

Id | Name | Length | Distance
1  | AB1  | 100    | 3600
2  | AB2  | 50     | 
2  | AB3  | 100    | 
3  | AB4  | 50     | 
4  | AB5  | 100    | 
5  | AB6  | 50     | 

但我想要一个sql代码更新到此(占用前一个距离并添加长度)

Id | Name | Length | Distance
1  | AB1  | 100    | 3600
2  | AB2  | 50     | 3650
3  | AB3  | 100    | 3750
4  | AB4  | 50     | 3800
5  | AB5  | 100    | 3900
6  | AB6  | 50     | 3950

我在想像

这样的东西
UPDATE Table
SET Distance = (SELECT Distinct FROM table WHERE id=id-1)+Length
etc...

2 个答案:

答案 0 :(得分:1)

如果你有窗口功能

Declare @Table table (ID int,Name varchar(25),Length int,Distance int)
Insert into @Table values
(1,'AB1',100,3600),
(2,'AB2',50,0 ),
(3,'AB3',100,0),
(4,'AB4',50,0),
(5,'AB5',100,0),
(6,'AB6',50,0)

Select ID,Name,Length
      ,Distance = sum(IIF(Distance>0,Distance,Length)) over (Order by ID)
    From @Table

返回

ID  Name    Length  Distance
1   AB1     100     3600
2   AB2     50      3650
3   AB3     100     3750
4   AB4     50      3800
5   AB5     100     3900
6   AB6     50      3950
  

这是2008版本 - 返回与上面相同

Declare @Table table (ID int,Name varchar(25),Length int,Distance int)
Insert into @Table values
(1,'AB1',100,3600),
(2,'AB2',50,0 ),
(3,'AB3',100,0),
(4,'AB4',50,0),
(5,'AB5',100,0),
(6,'AB6',50,0)

Select A.ID
      ,A.Name
      ,A.Length
      ,Distance = Sum(case when B.Distance>0 then B.Distance else B.Length end)
 From  @Table A
 Join  @Table B on (B.ID<=A.ID)
 Group By A.ID
      ,A.Name
      ,A.Length
 Order By 1
  

如果您有兴趣,我也有

Select [dbo].[udf-Date-Elapsed](@Date1,@Date2)

返回

002:16:00:00   -- Or 2 Day 16 Hours 0 Minutes

答案 1 :(得分:0)

使用公用表表达式并假设您的ID是顺序的(否则使用ROW_NUMBER()函数来确保顺序ID:

DECLARE @mytable AS TABLE (
    Id INT,
    Name VARCHAR(10),
    Length INT,
    Distance INT
)
INSERT INTO @myTable (id, Name, Length, Distance)
VALUES (1, 'AB1', 100, 3600),
(2, 'AB2', 50, NULL),
(3, 'AB3', 100, NULL),
(4, 'AB4', 50, NULL)

SELECT * FROM @myTable;

; WITH cte AS (
    SELECT TOP 1 Id, Name, Length, Distance FROM @myTable
    UNION ALL
    SELECT mt.Id, mt.Name, mt.Length, cte.Distance + ISNULL(mt.Length, 0)
    FROM cte
    INNER JOIN @myTable mt ON mt.Id-1 = cte.Id
)

SELECT * FROM cte;