根据sql server中的上一行修改当前行

时间:2014-11-19 06:11:55

标签: sql-server

我有这样的结果集:

YearMonth  Sales
201411     100
201412     100
201501     100
201502     100
201503     100
201504     100
201505     100
201506     100
201507     100
201508     100

需要添加另一行,销售额比上个月多4%。例如,我的结果应该是

YearMonth  Sales  New Sales
201411     100    100.00
201412     100    104.00
201501     100    108.16
201502     100    112.49
201503     100    116.99
201504     100    121.67
201505     100    126.53
201506     100    131.59
201507     100    136.86
201508     100    142.33

请帮助我找到最好的方法。

3 个答案:

答案 0 :(得分:0)

是的可能。但首先你必须改变表并添加额外的列NewSales然后尝试使用此链接 https://dba.stackexchange.com/questions/34243/update-row-based-on-match-to-previous-row  我想你可以通过这个链接完成它 sql server也支持SQL Server中的一些" Computed Columns with Persisted Values" 使用它你可以指定你想要的公式,然后根据你的公式

自动创建新的列值

答案 1 :(得分:0)

完全满足您的要求。弄清楚需要很长时间。只需使用您的表名更改#Temp表名,并验证列名。

DECLARE @nCurrentSale FLOAT
DECLARE @nYeatDate INT
DECLARE @nSale FLOAT

CREATE TABLE #TempNEW(YearMonth VARCHAR(10), Sales FLOAT, NewSale FLOAT) 
SELECT TOP 1 @nCurrentSale =  Sales FROM #Temp 
   ORDER BY (CAST('01/' + SUBSTRING (CAST(YearMonth AS VARCHAR), 5 , 2) + '/' + SUBSTRING (CAST(YearMonth AS 
        VARCHAR), 0 , 5) AS DATETIME)) ASC

 DECLARE Cursor1 CURSOR FOR
        SELECT YearMonth, Sales FROM #Temp
        ORDER BY (CAST('01/' + SUBSTRING (CAST(YearMonth AS VARCHAR), 5 , 2) + '/' + SUBSTRING (CAST(YearMonth AS 
            VARCHAR), 0 , 5) AS DATETIME)) ASC

    OPEN Cursor1

    FETCH NEXT FROM Cursor1 INTO @nYeatDate, @nSale

    WHILE @@FETCH_STATUS = 0
    BEGIN  
        INSERT INTO #TempNEW(YearMonth, Sales, NewSale) VALUES(@nYeatDate, @nSale, CAST(@nCurrentSale AS DECIMAL(12,2)))

        SET @nCurrentSale = @nCurrentSale + ((@nCurrentSale/100) * 4)

        FETCH NEXT FROM Cursor1 INTO @nYeatDate, @nSale
    END

    CLOSE Cursor1
    DEALLOCATE Cursor1

SELECT * FROM #TempNEW

通知我状态。

答案 2 :(得分:0)

这里有两个想法......如果我理解用例,那就不是很清楚......此解决方案也适用于SQL 2012及以上

所以给出了表

CREATE TABLE [dbo].[LagExample](
    [YearMonth] [nvarchar](100) NOT NULL,
    [Sales] [money] NOT NULL
) 

第一个是相当简单的,只是假设您希望将百分比增加的幅度基于它之前的天数......

;WITH cte
as
(
    SELECT YearMonth,
       ROW_NUMBER()  OVER (ORDER BY YearMonth) - 1 AS SalesEntry,
        cast(LAG(Sales, 1,Sales) OVER (ORDER BY YearMonth) as float) as Sales
    FROM LagExample
)
SELECT YearMonth, 
        Sales,
       cast(Sales * POWER(cast(1.04 as float), SalesEntry) AS decimal(10,2)) as NewSales
FROM cte

第二个使用递归CTE来计算沿着月份移动的值。 这是关于递归CTE的良好链接 http://www.codeproject.com/Articles/683011/How-to-use-recursive-CTE-calls-in-T-SQL

;with data
as
(
    SELECT Lead(le.YearMonth, 1, null) OVER (ORDER BY le.YearMonth) as NextYearMonth, 
            cast(le.Sales as Decimal(10,4)) as Sales,
            le.YearMonth
    FROM LagExample le
)
,cte
as
(
    SELECT *
    FROM data
    Where YearMonth = '201411'
    UNION ALL
    SELECT 
       data.NextYearMonth, 
       cast(cte.Sales * 1.04 as Decimal(10,4)) as Sales,
       data.YearMonth
    From cte join 
        data on data.YearMonth = cte.NextYearMonth
)
SELECT YearMonth, cast(Sales as Decimal(10,2))
FROM cte
order by YearMonth