T-SQL - 使用子查询进行增量更新

时间:2014-06-02 17:39:57

标签: sql-server tsql

我尝试使用SQL Server 2012编写增量更新语句。

当前数据:

RecNo    Budget_ID  Item_Code  Revision
---------------------------------------
1        16         xxx        2
2        16         xxx        NULL
3        16         xxx        NULL 
12       19         yyy        3
13       19         yyy        NULL
14       19         yyy        NULL 
15       19         yyy        NULL 

预期结果:

RecNo    Budget_ID  Item_Code  Revision
---------------------------------------
1        16         xxx        2
2        16         xxx        1
3        16         xxx        0
12       19         yyy        3
13       19         yyy        2
14       19         yyy        1
15       19         yyy        0

然而,采用以下方法,我最终得到了如下结果集。

UPDATE a
SET a.Revision = (SELECT MIN(b.Revision) 
                  FROM [dbo].[foo] b 
                  WHERE b.item_code = a.item_code 
                    AND b.budget_id = a.budget_id
                  GROUP BY b.item_code ) -1
FROM [dbo].[foo] a
WHERE a.Revision is NULL

结果:

RecNo    Budget_ID  Item_Code  Revision
---------------------------------------
1        16         xxx        2
2        16         xxx        1
3        16         xxx        1
12       19         yyy        3
13       19         yyy        2
14       19         yyy        2
15       19         yyy        2

任何人都可以帮助我做到这一点吗?

提前致谢!

4 个答案:

答案 0 :(得分:3)

试试这个:

;with cte as
(select *, row_number() over (partition by budget_id order by rec_no desc) rn from dbo.foo)

update cte
set revision = rn - 1

基本上,由于revision值似乎随着rec_no的增加而减少,我们只需使用row_number()函数获取所有记录子集中每条记录的行号特定budget_id,按rec_no的降序排序。由于row_number()的最小可能值为1,因此我们减去1,以便分区中的最后一条记录将revision设置为0而不是1.

您可以测试代码here

答案 1 :(得分:0)

我在此链接https://stackoverflow.com/a/13629639/1692632

中找到了此示例

首先,您可以为某个变量选择MIN值,然后您可以通过同时减少变量来更新表。

DECLARE @table TABLE (ID INT, SomeData VARCHAR(10))

INSERT INTO @table (SomeData, ID) SELECT 'abc', 6 ;
INSERT INTO @table (SomeData) SELECT 'def' ;
INSERT INTO @table (SomeData) SELECT 'ghi' ;
INSERT INTO @table (SomeData) SELECT 'jkl' ;
INSERT INTO @table (SomeData) SELECT 'mno' ;
INSERT INTO @table (SomeData) SELECT 'prs' ;

DECLARE @i INT = (SELECT ISNULL(MIN(ID),0) FROM @table)

UPDATE @table
SET ID = @i, @i = @i - 1
WHERE ID IS NULL

SELECT *
FROM @table

答案 2 :(得分:0)

我不确定这是否可行,但你可以试试

Update  top(1) a
SET a.Revision = (Select MIN(b.Revision) 
FROM [dbo].[foo] b where b.item_code = a.item_code and b.budget_id = a.budget_id
group by b.item_code ) -1
FROM [dbo].[foo] a
WHERE a.Revision is NULL

并重复,直到没有任何变化为止

答案 3 :(得分:0)

Update Data
set Revision = x.Revision
from 
    (select RecNo, Budget_ID, Item_Code, case when Revision is null then ROW_NUMBER() over(partition by Budget_ID order by RecNo desc) - 1 else Revision end Revision
     from Data  
    ) x
where x.RecNo = data.RecNo

您基本上使用ROW_NUMBER()为每个Budget_ID向后计数,并使用该行数减去1,其中Revision为null。这与Shree的答案基本相同,只是没有CTE。