none
求一条SQL,下一条记录减去上一条记录 RRS feed

  • 问题

  • 表结构:

    ID              DATE                VALUE      V

    201        20110101            100

    201        20110102             200

    202        20110101           10

    202         20110102          20

    202        20110103            30

    要求:根据ID分类,DATE排序,用VALUE的后一条记录减去前一条记录,获得的值作为后一条记录V的值。

    例如:201      200-100=100   100就是201        20110102             200     100(V)

    202     20-10=10   10就是202         20110102          20  10(V)

    202     35-20=15    15就是202        20110103            35   15(V)

    最终表结构就是:

    ID              DATE                VALUE      V

    201        20110101            100          0

    201        20110102             200         100

    202        20110101           10              0

    202         20110102          20              10

    202        20110103            35              15

    2012年6月13日 3:36

答案

  • 之前的回复没有看清楚棂主的需求,回复作废,排序+分组还是用 row_number 去处理吧(主要是排序)

    能保障顺序可以使用我的方法 (要改一下,之前理解的意思有误),不过,由于SQL Server 仅在 ORDER BY 的情况下保证顺序,所以仅供参考

    DECLARE
    	@id int,
    	@value_1 int,
    	@value_2 int
    ;
    UPDATE @TB SET
    	@value_2 = CASE
    				WHEN @id = id THEN VALUE - @value_1
    				ELSE 0
    			END,
    	@value_1 = VALUE,
    	@id = id,
    
    	V = @value_2
    ;
    

    • 已编辑 zjcxc.邹建 2012年6月13日 9:10
    • 已标记为答案 邵乐 2012年6月13日 11:15
    2012年6月13日 6:48

全部回复

  • 202        20110103            35              15    没有结果
    2012年6月13日 5:10
  • 之前的回复没有看清楚棂主的需求,回复作废,排序+分组还是用 row_number 去处理吧(主要是排序)

    能保障顺序可以使用我的方法 (要改一下,之前理解的意思有误),不过,由于SQL Server 仅在 ORDER BY 的情况下保证顺序,所以仅供参考

    DECLARE
    	@id int,
    	@value_1 int,
    	@value_2 int
    ;
    UPDATE @TB SET
    	@value_2 = CASE
    				WHEN @id = id THEN VALUE - @value_1
    				ELSE 0
    			END,
    	@value_1 = VALUE,
    	@id = id,
    
    	V = @value_2
    ;
    

    • 已编辑 zjcxc.邹建 2012年6月13日 9:10
    • 已标记为答案 邵乐 2012年6月13日 11:15
    2012年6月13日 6:48
  • declare @T table
    ([ID] int,[DATE] datetime,[VALUE] int,[V] int)
    insert @T
    select 201,'20110101',100,null union all
    select 201,'20110102',200,null union all
    select 202,'20110101',10,null union all
    select 202,'20110102',20,null union all
    select 202,'20110103',35,null
    
    ;with maco as
    (
    select row_number() over (partition by [ID] order by [DATE]) as rid,* from @T
    ),t as(
    select a.*,isnull(a.[VALUE]-b.value,0) as nvalue 
    from maco a left join maco b on a.id=b.id and a.rid=b.rid+1
    )
    
    update @T
    set V=b.nvalue
    from @T a left join t b on a.id=b.id and a.date=b.date
    
    select * from @T
    /*
    ID          DATE                    VALUE       V
    ----------- ----------------------- ----------- -----------
    201         2011-01-01 00:00:00.000 100         0
    201         2011-01-02 00:00:00.000 200         100
    202         2011-01-01 00:00:00.000 10          0
    202         2011-01-02 00:00:00.000 20          10
    202         2011-01-03 00:00:00.000 35          15
    */

    2012年6月13日 7:02
    版主