我尝试使用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
任何人都可以帮助我做到这一点吗?
提前致谢!
答案 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。