Sql server 更改内容的循环
我真的很挣扎,应该是直截了当的,我有一个表格,格式如下:Sql server 更改内容的循环,sql-server,Sql Server,我真的很挣扎,应该是直截了当的,我有一个表格,格式如下: ID Date Agent State 1 02/01/2015 77777 Work 2 03/01/2015 77777 X 3 04/01/2015 77777 X 4 05/01/2015 77777 X 5 06/01/2015 77777 X 6 07/01/2015 77777 SICK 7 08/01/2015 77777 SICK 8
ID Date Agent State
1 02/01/2015 77777 Work
2 03/01/2015 77777 X
3 04/01/2015 77777 X
4 05/01/2015 77777 X
5 06/01/2015 77777 X
6 07/01/2015 77777 SICK
7 08/01/2015 77777 SICK
8 09/01/2015 77777 X
9 02/01/2015 88888 Work
10 03/01/2015 88888 Work
11 04/01/2015 88888 SICK
12 05/01/2015 88888 SICK
13 06/01/2015 88888 X
14 07/01/2015 88888 X
15 08/01/2015 88888 SICK
16 09/01/2015 88888 Work
我需要创建一个循环,用前一条记录的状态替换X,直到它到达一个不包含X的字段。它还必须适应代理ID的变化,并且如果代理的第一条记录是X,那么它应该显示“工作”
预期输出如下所示:
Date Agent State
02/01/2015 77777 Work
03/01/2015 77777 Work
04/01/2015 77777 Work
05/01/2015 77777 Work
06/01/2015 77777 Work
07/01/2015 77777 SICK
08/01/2015 77777 SICK
09/01/2015 77777 SICK
02/01/2015 88888 Work
03/01/2015 88888 Work
04/01/2015 88888 SICK
05/01/2015 88888 SICK
06/01/2015 88888 SICK
07/01/2015 88888 SICK
08/01/2015 88888 SICK
09/01/2015 88888 Work
我使用的是sql server management studio 2008如果ID为1的行是
'X'
,则可以在update语句中使用子查询,并使用合并
来分配'Work'
update #statetable
set [State] = COALESCE((select top 1 s2.[State] from #statetable as s2 where s2.ID < s1.ID AND s2.State <> 'X' order by s2.ID ),'Work')
from #statetable as s1
Where s1.[State] = 'X'
最直接的方法是使用光标
DECLARE @id int
DECLARE @agent int
DECLARE @state varchar(10)
DECLARE @previousAgent int = 0
DECLARE @previousState varchar(10) = 'Work'
DECLARE myCursor CURSOR FOR
SELECT ID, Agent, State
FROM MyTable
ORDER BY Agent, Date
OPEN myCursor
FETCH NEXT FROM myCursor INTO @id, @agent, @state
WHILE @@FETCH_STATUS = 0
BEGIN
IF @agent <> @previousAgent
BEGIN
SET @previousAgent = @agent
SET @previousState = 'Work'
END
IF @state = 'X'
UPDATE MyTable SET State = @previousState WHERE ID = @id
ELSE
SET @previousState = @state
FETCH NEXT FROM myCursor INTO @id, @agent, @state
END
CLOSE myCursor
DEALLOCATE myCursor
DECLARE@id int
声明@agent int
声明@state varchar(10)
声明@previousAgent int=0
声明@previousState varchar(10)=“工作”
将myCursor声明为
选择ID、代理、状态
从MyTable
代理人的订单,日期
打开我的光标
从myCursor获取下一个到@id、@agent、@state
而@@FETCH\u STATUS=0
开始
如果@agent@previousAgent
开始
设置@previousAgent=@agent
SET@previousState='Work'
结束
如果@state='X'
更新MyTable集合状态=@previousState,其中ID=@ID
其他的
设置@previousState=@state
从myCursor获取下一个到@id、@agent、@state
结束
关闭我的光标
取消分配我的游标
Fiddle:请详细说明这一部分“它还必须适应代理ID的变化,并且如果代理的第一个记录是X,那么它应该显示“工作”嗨,我的数据有3种状态(“X”=休息日或假日、生病或工作)如果代理的第一个状态为=“X”,那么我需要将其更改为“工作”因此循环将填充下面的记录,直到达到另一个“工作”或“生病”状态。代理id中的更改应重置循环,使其不会携带来自前一代理的状态。我希望这是有意义的。它看起来只使用ID和状态就可以了,但是当我尝试引入日期和代理ID字段时,它就不起作用了。它似乎改变了X的工作,即使前面的记录有一个生病的状态。我已经包括了日期和代理字段在我的样本中,它的工作和结果符合您的预期结果。可能是SQL脚本中的其他部分导致了错误。非常感谢Ruud,感谢您的帮助。
DECLARE @id int
DECLARE @agent int
DECLARE @state varchar(10)
DECLARE @previousAgent int = 0
DECLARE @previousState varchar(10) = 'Work'
DECLARE myCursor CURSOR FOR
SELECT ID, Agent, State
FROM MyTable
ORDER BY Agent, Date
OPEN myCursor
FETCH NEXT FROM myCursor INTO @id, @agent, @state
WHILE @@FETCH_STATUS = 0
BEGIN
IF @agent <> @previousAgent
BEGIN
SET @previousAgent = @agent
SET @previousState = 'Work'
END
IF @state = 'X'
UPDATE MyTable SET State = @previousState WHERE ID = @id
ELSE
SET @previousState = @state
FETCH NEXT FROM myCursor INTO @id, @agent, @state
END
CLOSE myCursor
DEALLOCATE myCursor