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

解决方案 »

  1.   

    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 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”出现时就多加了几次,大家帮改改,谢谢
      

  2.   

    --在你的代碼的基礎上這麼修改下可以得到你要的結果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 
    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
      

  3.   

    麻烦你把相同标志位的数据求平均,并且保留当前标志位最大的S_TIME。而无效数据段(等于4或5)删除例如这组数据的结果是:(3+2+2+1)/4     15      1-------(等于4,5的删除了)(3+3+2)/3       20      2-------(等于4,5的删除了)(1+2+3)/3       24      3........
    朋友麻烦你,我在线等你
      

  4.   

    hellowork(一两清风) 麻烦你也给点见解好么帮我把功能再完善一点,谢谢
      

  5.   

    谢谢你的关注,就是在你给的修改的基础上,增加排序,求平均,和删除功能把标志位相同部分的数据(S_ID)的求平均(标志位连续相同的那部分),保留相同标志位(最后的采集时间S_ID)然后把S_ID为null的删除。例如这组数据的结果是:
       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
      

  6.   

    不好意思,错了点,修改一下把标志位相同部分的数据(S_DATA)的求平均(标志位 <连续> 相同的那部分),保留相同标志位(最后的采集时间S_ID)上面给出的结果,前面的(..+..+..)/.. ,拿第一段连续标志位(S_ID=1)说,就是:第一段连续标志位为 1 的数据求平均,然后时间位 S_TIME 保留最大的 15.谢谢
      

  7.   

    楼主的问题的原帖找到了:http://topic.csdn.net/t/20061031/14/5122321.html
    怪不得看代码这么熟悉。
    下面对原算法改进一下(非常苦恼,无法把帖子一次贴出来,必须拆开,请楼主自己按顺序连接一下吧,不知道CSDN出了什么问题):
      

  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
            
    ----查看更新   
    select * from @t   
       
    ----清除测试环境   
    drop table #tmp  
      

  9.   

    /*结果
    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
    */
      

  10.   

    /*如果仅是按标志位分组不分方向求平均值倒比较简单:*/
    ----创建测试数据   
    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
    */
      

  11.   

    如果仍要保持S_ID:
    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
    */
      

  12.   

    我做了些修改,就是把数据换成了查询某个表insert into @t select * from text_one结果下面这行有错:select S_DATA = avg(S_DATA),S_TIME = max(S_TIME),S_ID子查询返回的值多于一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。
      

  13.   

    --第一部分按照如下修改可以精簡不少代碼,也可以達到效果。----创建测试数据 
    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  
      

  14.   

    --以下是兩部分結合起來的效果,你可以看到你要的兩個結果集
    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
      

  15.   

    xia_zi() ( ) 信誉:100    Blog   加为好友  2007-06-14 08:42:40  得分: 0  
     
     
       我做了些修改,就是把数据换成了查询某个表insert into @t select * from text_one结果下面这行有错:select S_DATA = avg(S_DATA),S_TIME = max(S_TIME),S_ID子查询返回的值多于一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。
      
     
    --------------是哪個的代碼出錯?我的還是hellowork(一两清风) 的?最好能將這句的完整代碼貼出來看,不然看不出問題。
      

  16.   

    hellowork(一两清风)的出现上面的问题你的代码号精简阿,我再想想,呵,谢谢大家帮我这么多,请问怎么给分阿