if object_id('tempdb..#tmp') is not null
drop table #tmp
GO
----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----从上至下更新
declare @data int,@flag int
set @flag = 1
UPDATE @t SET
/*使用@data作为判断S_DATA连续为4,5,6无效数据的标志*/
@data = case
when @data between 4 and 6 and S_DATA between 4 and 6 then 888
else S_DATA end,
@flag =
case
when S_DATA between 1 and 3 then @flag
when S_DATA between 4 and 6 and @data <> 888 then @flag + 1
when S_DATA between 4 and 6 and @data = 888 then @flag
else 1
end,
S_ID =
case
when S_DATA between 4 and 6
then null
else @flag
end
----生成用于从下至上更新的临时表
select * into #tmp from @t order by S_TIME DESC
----从上至下更新临时表(相当于从下至上更新原表)
declare @ bit
/*更新S_ID时使用的判断标志*/
set @flag = 1
UPDATE #tmp SET @ =
case
when @ = 1 then 1
else
case when S_DATA = 6 then 1 end
/*如果遇到S_DATA = 6的行,则之后的行禁止被更新*/
end,
/*使用@data作为判断S_DATA连续为4,5,6无效数据的标志*/
@data =
case
when @data between 4 and 6 and S_DATA between 4 and 6 then 888 else S_DATA end,
@flag =
case
when S_DATA between 1 and 3 then @flag
when S_DATA between 4 and 6 and @data <> 888 then @flag + 1
when S_DATA between 4 and 6 and @data = 888 then @flag
else 1
end,
S_ID = case
when @ = 1 then S_ID
/*第一次更新时S_DATA = 6之前的行的S_ID不再更新,保持原值*/
else
case
when S_DATA between 4 and 6 then null
else @flag
end
end
----更新原表的S_ID
update a set S_ID = b.S_ID from @t as a
inner join #tmp as b on a.S_DATA = b.S_DATA and a.S_TIME = b.S_TIME
----查看更新
select * from @t
----清除测试环境
drop table #tmp
drop table #tmp
GO
----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----从上至下更新
declare @data int,@flag int
set @flag = 1
UPDATE @t SET
/*使用@data作为判断S_DATA连续为4,5,6无效数据的标志*/
@data = case
when @data between 4 and 6 and S_DATA between 4 and 6 then 888
else S_DATA end,
@flag =
case
when S_DATA between 1 and 3 then @flag
when S_DATA between 4 and 6 and @data <> 888 then @flag + 1
when S_DATA between 4 and 6 and @data = 888 then @flag
else 1
end,
S_ID =
case
when S_DATA between 4 and 6
then null
else @flag
end
----生成用于从下至上更新的临时表
select * into #tmp from @t order by S_TIME DESC
----从上至下更新临时表(相当于从下至上更新原表)
declare @ bit
/*更新S_ID时使用的判断标志*/
set @flag = 1
UPDATE #tmp SET @ =
case
when @ = 1 then 1
else
case when S_DATA = 6 then 1 end
/*如果遇到S_DATA = 6的行,则之后的行禁止被更新*/
end,
/*使用@data作为判断S_DATA连续为4,5,6无效数据的标志*/
@data =
case
when @data between 4 and 6 and S_DATA between 4 and 6 then 888 else S_DATA end,
@flag =
case
when S_DATA between 1 and 3 then @flag
when S_DATA between 4 and 6 and @data <> 888 then @flag + 1
when S_DATA between 4 and 6 and @data = 888 then @flag
else 1
end,
S_ID = case
when @ = 1 then S_ID
/*第一次更新时S_DATA = 6之前的行的S_ID不再更新,保持原值*/
else
case
when S_DATA between 4 and 6 then null
else @flag
end
end
----更新原表的S_ID
update a set S_ID = b.S_ID from @t as a
inner join #tmp as b on a.S_DATA = b.S_DATA and a.S_TIME = b.S_TIME
----查看更新
select * from @t
----清除测试环境
drop table #tmp
2 13 1
2 14 1
1 15 1
4 16 NULL
5 17 NULL
4 16 NULL
4 16 NULL
3 18 3
3 19 3
2 20 3
4 21 NULL
1 22 4
2 23 4
3 24 4
5 25 NULL
4 16 NULL
4 16 NULL
4 16 NULL
3 26 6
2 27 6
6 28 NULL
2 29 4
3 30 4
4 31 NULL
1 32 3
1 33 3
2 34 3
5 35 NULL
2 36 2
3 37 2
4 38 NULL
1 39 1
2 40 1
3 41 1运行结果是这个。但我想要的是后面的标志是先递增再递减,例如:12344321问题就出现在当有多个“4”或“5”出现时就多加了几次,大家帮改改,谢谢
drop table #tmp
GO
----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----从上至下更新
declare @data int,@flag int
select @flag = 1, @data = 0UPDATE @t SET
@flag = (Case When (@data Between 4 And 6) And (S_DATA Not Between 4 And 6) Then @flag + 1 Else @flag End),
S_ID = (Case When (S_DATA Between 4 And 6) Then Null Else @flag End),
@data = S_DATA----生成用于从下至上更新的临时表
select * into #tmp from @t order by S_TIME DESC
----从上至下更新临时表(相当于从下至上更新原表)
declare @ bit
/*更新S_ID时使用的判断标志*/
set @flag = 1
UPDATE #tmp SET @ =
case
when @ = 1 then 1
else
case when S_DATA = 6 then 1 end
/*如果遇到S_DATA = 6的行,则之后的行禁止被更新*/
end,
/*使用@data作为判断S_DATA连续为4,5,6无效数据的标志*/
@data =
case
when @data between 4 and 6 and S_DATA between 4 and 6 then 888 else S_DATA end,
@flag =
case
when S_DATA between 1 and 3 then @flag
when S_DATA between 4 and 6 and @data <> 888 then @flag + 1
when S_DATA between 4 and 6 and @data = 888 then @flag
else 1
end,
S_ID = case
when @ = 1 then S_ID
/*第一次更新时S_DATA = 6之前的行的S_ID不再更新,保持原值*/
else
case
when S_DATA between 4 and 6 then null
else @flag
end
end
----更新原表的S_ID
update a set S_ID = b.S_ID from @t as a
inner join #tmp as b on a.S_DATA = b.S_DATA and a.S_TIME = b.S_TIME
----查看更新
select * from @t
----清除测试环境
drop table #tmp
朋友麻烦你,我在线等你
S_DATA S_TIME S_ID(3+2+2+1)/4 15 1-------(等于4,5的删除了)(3+3+2)/3 20 2-------(等于4,5的删除了)(1+2+3)/3 24 3-------(等于4,5的删除了)(3+2)/2 27 4-------(等于4,5的删除了)(2+3)/2 30 4-------(等于4,5的删除了)(1+1+2)/3 34 3-------(等于4,5的删除了)(2+3)/2 37 2-------(等于4,5的删除了)(1+2+3)/3 41 1
怪不得看代码这么熟悉。
下面对原算法改进一下(非常苦恼,无法把帖子一次贴出来,必须拆开,请楼主自己按顺序连接一下吧,不知道CSDN出了什么问题):
drop table #tmp
GO
----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----从上至下更新(更新到S_DATA=6时停止更新)
declare @data int,@flag int,@isend bit
set @flag = 1
set @isend = 0
update @t set
@isend = case when S_DATA = 6 then 1 else @isend end,
@flag = case when @data in(4,5,6) and S_DATA not in(4,5,6) then @flag + 1 else @flag end,
S_ID = case when @isend = 1 then S_ID else case when S_DATA in(4,5,6) then null else @flag end end,
@data = S_DATA----生成临时表,用于实现从下至上更新(更新到S_DATA=6时停止更新)
select * into #tmp from @t order by S_TIME DESC /*按S_TIME降序*/
set @flag = 1
set @isend = 0
update #tmp set
@isend = case when S_DATA = 6 then 1 else @isend end,
@flag = case when @data in(4,5,6) and S_DATA not in(4,5,6) then @flag + 1 else @flag end,
S_ID = case when @isend = 1 then S_ID else case when S_DATA in(4,5,6) then null else @flag end end,
@data = S_DATA----更新原表的S_ID
update a set S_ID = b.S_ID from @t as a
inner join #tmp as b on a.S_DATA = b.S_DATA and a.S_TIME = b.S_TIME
----查看更新
select * from @t
----清除测试环境
drop table #tmp
S_DATA S_TIME S_ID
----------- ----------- -----------
3 12 1
2 13 1
2 14 1
1 15 1
4 16 NULL
5 17 NULL
4 16 NULL
4 16 NULL
3 18 2
3 19 2
2 20 2
4 21 NULL
1 22 3
2 23 3
3 24 3
5 25 NULL
4 16 NULL
4 16 NULL
4 16 NULL
3 26 4
2 27 4
6 28 NULL
2 29 4
3 30 4
4 31 NULL
1 32 3
1 33 3
2 34 3
5 35 NULL
2 36 2
3 37 2
4 38 NULL
1 39 1
2 40 1
3 41 1
*/
----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----更新标志位,作为分组列
declare @data int,@flag int
set @flag = 1
update @t set
@flag = case when @data in(4,5,6) and S_DATA not in(4,5,6) then @flag + 1 else @flag end,
S_ID = case when S_DATA in(4,5,6) then null else @flag end,
@data = S_DATA
----求平均值
select S_DATA = avg(S_DATA),S_TIME = max(S_TIME),S_ID
from @t where S_ID is not null group by S_ID
/*结果
S_DATA S_TIME S_ID
----------- ----------- -----------
2 15 1
2 20 2
2 24 3
2 27 4
2 30 5
1 34 6
2 37 7
2 41 8
*/
if object_id('tempdb..#tmp') is not null
drop table #tmp
GO
----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----从上至下更新(更新到S_DATA=6时停止更新)
declare @data int,@flag int,@isend bit
set @flag = 1
set @isend = 0
update @t set
@isend = case when S_DATA = 6 then 1 else @isend end,
@flag = case when @data in(4,5,6) and S_DATA not in(4,5,6) then @flag + 1 else @flag end,
S_ID = case when @isend = 1 then S_ID else case when S_DATA in(4,5,6) then null else @flag end end,
@data = S_DATA----生成临时表,用于实现从下至上更新(更新到S_DATA=6时停止更新)
select * into #tmp from @t order by S_TIME DESC /*按S_TIME降序*/
set @flag = 1
set @isend = 0
update #tmp set
@isend = case when S_DATA = 6 then 1 else @isend end,
@flag = case when @data in(4,5,6) and S_DATA not in(4,5,6) then @flag + 1 else @flag end,
S_ID = case when @isend = 1 then S_ID else case when S_DATA in(4,5,6) then null else @flag end end,
@data = S_DATA----更新原表的S_ID
update a set S_ID = b.S_ID from @t as a
inner join #tmp as b on a.S_DATA = b.S_DATA and a.S_TIME = b.S_TIME----按标志位和方向汇总求S_DATA平均值
select S_DATA = avg(S_DATA),S_TIME = max(S_TIME),S_ID
from @t where S_ID is not null and S_TIME < (select S_TIME from @t where S_DATA = 6)
group by S_ID
UNION ALL
select S_DATA = avg(S_DATA),S_TIME = max(S_TIME),S_ID
from @t where S_ID is not null and S_TIME > (select S_TIME from @t where S_DATA = 6)
group by S_ID order by S_TIME
----清除测试环境
drop table #tmp /*结果
S_DATA S_TIME S_ID
----------- ----------- -----------
2 15 1
2 20 2
2 24 3
2 27 4
2 30 4
1 34 3
2 37 2
2 41 1
*/
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
----从上至下更新
declare @data int,@flag int, @ bit
select @flag = 1, @data = 0, @ = 0UPDATE @t SET
@ = (Case S_DATA When 6 Then 1 Else @ End),
@flag = (Case When (@data Between 4 And 5) And (S_DATA Not Between 4 And 5) Then (Case @ When 0 Then @flag + 1 Else @flag- 1 End) Else @flag End),
S_ID = (Case When (S_DATA Between 4 And 6) Then Null Else @flag End),
@data = S_DATA----查看更新
select * from @t
if object_id('tempdb..#tmp') is not null
drop table #tmp
GO ----创建测试数据
declare @t table(S_DATA int,S_TIME int,S_ID int)
insert @t
select 3, 12, null union all
select 2, 13, null union all
select 2, 14, null union all
select 1, 15, null union all
select 4, 16, null union all
select 5, 17, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 18, null union all
select 3, 19, null union all
select 2, 20, null union all
select 4, 21, null union all
select 1, 22, null union all
select 2, 23, null union all
select 3, 24, null union all
select 5, 25, null union all
select 4, 16, null union all
select 4, 16, null union all
select 4, 16, null union all
select 3, 26, null union all
select 2, 27, null union all
select 6, 28, null union all
select 2, 29, null union all
select 3, 30, null union all
select 4, 31, null union all
select 1, 32, null union all
select 1, 33, null union all
select 2, 34, null union all
select 5, 35, null union all
select 2, 36, null union all
select 3, 37, null union all
select 4, 38, null union all
select 1, 39, null union all
select 2, 40, null union all
select 3, 41, null
select *, 0 As into #tmp from @t----从上至下更新
--得到第一步的結果
declare @data int,@flag int, @ bit
select @flag = 1, @data = 0, @ = 0UPDATE @t SET
@ = (Case S_DATA When 6 Then 1 Else @ End),
@flag = (Case When (@data Between 4 And 5) And (S_DATA Not Between 4 And 5) Then (Case @ When 0 Then @flag + 1 Else @flag- 1 End) Else @flag End),
S_ID = (Case When (S_DATA Between 4 And 6) Then Null Else @flag End),
@data = S_DATA----查看更新
select * from @t --得到第二步的結果
select @flag = 1, @data = 0, @ = 0UPDATE #tmp SET
@ = (Case S_DATA When 6 Then 1 Else @ End),
= @,
@flag = (Case When (@data Between 4 And 5) And (S_DATA Not Between 4 And 5) Then (Case @ When 0 Then @flag + 1 Else @flag- 1 End) Else @flag End),
S_ID = (Case When (S_DATA Between 4 And 6) Then Null Else @flag End),
@data = S_DATASelect AVG(S_DATA) As S_DATA, MAX(S_TIME) As S_TIME, S_ID From #tmp Where S_DATA Not In (4, 5, 6) Group By S_ID, Order By S_TIME----清除测试环境
drop table #tmp
我做了些修改,就是把数据换成了查询某个表insert into @t select * from text_one结果下面这行有错:select S_DATA = avg(S_DATA),S_TIME = max(S_TIME),S_ID子查询返回的值多于一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。
--------------是哪個的代碼出錯?我的還是hellowork(一两清风) 的?最好能將這句的完整代碼貼出來看,不然看不出問題。