我真的在努力应对直截了当的事情,我有一个表格如下:
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
答案 0 :(得分:1)
您可以在更新语句中使用子查询,如果ID为1的行为COALESCE
,则'Work'
可以指定'X'
。
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'
这是sqlfiddle of the code I used to test it.
注意:强>
如果您将表State
列声明为类型varchar
且没有长度,则会抛出错误。
字符串或二进制数据将被截断。
Because a varchar
without a length will default to 1.所以这样定义的表格不起作用。
CREATE TABLE #statetable ( [ID] int, [State] varchar );
答案 1 :(得分:1)
最直接的方法是使用光标。
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