2016-07-28 97 views
0

讓我們說我有這樣的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... 
+0

哪個RDBMS這是爲了什麼?請添加一個標籤來指定您是使用'mysql','postgresql','sql-server','oracle'還是'db2' - 或者其他的東西。 –

+2

這會更好地描述爲使用前面的*行*來計算(一列)當前*行*的值。 –

回答

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 
+0

在> –

+0

@DavidChen似乎有一個語法問題在SQL 2012上運行乾淨你在什麼版本? –

+0

SQL Server 2008 –

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;