@@版本1
使用sql Server 2008,我试图将值级联到列.我有一个包含组ID(GID)和Seq的表,其中包含组内记录的排序.对于存在的列,在本例中为Name和Salary – 我的真实表有超过50列,如果它们包含NULL,我需要使用包含非空值的该列的前一行的值更新NULL值.
这是一个可以说明这一点:
GID Seq Name Salary 1 1 James NULL 1 2 NULL 100 1 3 NULL NULL 2 1 NULL 81 2 2 Smith NULL 2 3 NULL NULL 3 1 Charles NULL 3 2 NULL NULL 3 3 Brown NULL 3 4 NULL 75 4 0 Ron 50 4 1 NULL 20 4 2 NULL NULL
我的结果应该是:
GID Seq Name Salary 1 1 James NULL 1 2 James 100 1 3 James 100 2 1 NULL 81 2 2 Smith 81 2 3 Smith 81 3 1 Charles NULL 3 2 Charles NULL 3 3 Brown NULL 3 4 Brown 75 4 0 Ron 50 4 1 Ron 20 4 2 Ron 20
我希望不使用动态sql,循环或游标来做到这一点.
简单测试用例的代码:
DECLARE @Test TABLE (GID int,Seq int,Name varchar(50),Salary decimal) INSERT INTO @Test VALUES (1,1,'James',NULL) INSERT INTO @Test VALUES (1,2,NULL,100.40) INSERT INTO @Test VALUES (1,3,NULL) INSERT INTO @Test VALUES (2,80.50) INSERT INTO @Test VALUES (2,'Smith',NULL) INSERT INTO @Test VALUES (3,'Charles','Brown',4,75) INSERT INTO @Test VALUES (4,'Ron',50) INSERT INTO @Test VALUES (4,20) INSERT INTO @Test VALUES (4,NULL) SELECT * FROM @Test
@@版本2
感谢GilM为@@版本1提供解决方案.我对此问题做了一些补充. Seq列中的起始编号可以是0或1.在第一个问题的解决方案中,递归CTE中的锚点指的是1,如果它是1或0怎么办?最后3行数据(GID = 4)被添加到此版本中的所有上述三个代码块中.
谢谢!
解决方法
这个怎么样?:
;WITH CTE AS ( SELECT GID,SEQ,Name,Salary FROM @Test t1 WHERE SEQ = (SELECT MIN(SEQ) FROM @Test t2 WHERE t2.GID = t1.GID) UNION ALL SELECT t.GID,t.SEQ,COALESCE(t.Name,c.Name),COALESCE(t.Salary,c.Salary) FROM CTE c JOIN @Test t ON t.GID = c.GID AND t.SEQ = c.SEQ+1 ) UPDATE t SET Name = c.Name,Salary = c.Salary FROM @Test t JOIN CTE c ON c.GID = t.GID AND c.Seq = t.SEQ