Sql server SQL Server按值分组=不带光标循环的上一个值

Sql server SQL Server按值分组=不带光标循环的上一个值,sql-server,performance,tsql,group-by,Sql Server,Performance,Tsql,Group By,我必须编写一个T-SQL来获取超速行(Max/Min/Avg),但条件是,如果任何行

我必须编写一个T-SQL来获取超速行(Max/Min/Avg),但条件是,如果任何行 例如,这是我的数据库表,它有标志,如果这一行是超速或没有

rownum  Time                overspeed   overspeedrowid
1   2015-12-06 06:18:46.283 0           0
2   2015-12-06 06:19:46.283 1           0
3   2015-12-06 06:20:46.283 1           0
4   2015-12-06 06:21:46.283 0           0
5   2015-12-06 06:22:46.283 0           0
6   2015-12-06 06:23:46.283 1           0
7   2015-12-06 06:24:46.283 1           0
8   2015-12-06 06:25:46.283 1           0
9   2015-12-06 06:26:46.283 1           0
10  2015-12-06 06:27:46.283 0           0
11  2015-12-06 06:28:46.283 0           0
12  2015-12-06 06:29:46.283 0           0
13  2015-12-06 06:30:46.283 1           0
14  2015-12-06 06:31:46.283 1           0
15  2015-12-06 06:32:46.283 1           0
16  2015-12-06 06:33:46.283 0           0
17  2015-12-06 06:34:46.283 0           0
18  2015-12-06 06:35:46.283 1           0
19  2015-12-06 06:36:46.283 0           0
20  2015-12-06 06:37:46.283 0           0
21  2015-12-06 06:38:46.283 0           0
22  2015-12-06 06:39:46.283 1           0
23  2015-12-06 06:40:46.283 1           0
我的计划是使用以下工具

  • 在行上循环,如果当前!=prev和prev=0,然后是新的过速宽值
  • 如果电流=prev且prev=1,则电流过速宽=prev过速宽
  • 通过超速从计算表最小/最大组中选择
  • 所以计算表必须是这样的

    rownum  Time                overspeed   overspeedrowid
    1   2015-12-06 06:18:46.283 0           0
    2   2015-12-06 06:19:46.283 1           1
    3   2015-12-06 06:20:46.283 1           1
    4   2015-12-06 06:21:46.283 0           0
    5   2015-12-06 06:22:46.283 0           0
    6   2015-12-06 06:23:46.283 1           2
    7   2015-12-06 06:24:46.283 1           2
    8   2015-12-06 06:25:46.283 1           2
    9   2015-12-06 06:26:46.283 1           2
    10  2015-12-06 06:27:46.283 0           0
    11  2015-12-06 06:28:46.283 0           0
    12  2015-12-06 06:29:46.283 0           0
    13  2015-12-06 06:30:46.283 1           3
    14  2015-12-06 06:31:46.283 1           3
    15  2015-12-06 06:32:46.283 1           3
    16  2015-12-06 06:33:46.283 0           0
    17  2015-12-06 06:34:46.283 0           0
    18  2015-12-06 06:35:46.283 1           4
    19  2015-12-06 06:36:46.283 0           0
    20  2015-12-06 06:37:46.283 0           0
    21  2015-12-06 06:38:46.283 0           0
    22  2015-12-06 06:39:46.283 1           5
    23  2015-12-06 06:40:46.283 1           5
    
    • 我尝试了一个游标,但它需要很多时间,因为生产数据大约是2000000行

    • 我尝试用join row-1更新,并将row-1与当前的fast进行比较,因为它只更新了第二行

    这是我所做的,但它只更新了第二行

    update #temp1 
    set #temp1.overspeedrowid = @a, @a = @a + 1 
    from #temp1 
    left join #temp1 prev on prev.rownum = #temp1.rownum - 1 
    where 
         (#temp1.overspeed != prev.overspeed and #temp1.overspeed = 1)
    
    update #temp1 
    set #temp1.overspeedrowid = prev. overspeedrowid 
    from #temp1 
    left join #temp1 prev on prev.rownum = #temp1.rownum - 1 
    where 
         (#temp1.overspeed = prev.overspeed and #temp1.overspeed = 1)
    

    在SQL Server 2012+中,可以使用
    lag()
    后跟“条件”累积和:

    select t.*,
           (case when overspeed = 0 then 0
                 else sum(OverSpeedFlag) over (order by time)
            end) as overspeedrowid
    from (select t.*,
                 (case when lag(overspeed) over (order by time) = 0 and overspeed = 1
                       then 1 else 0 
                  end) as OverSpeedFlag
          from #temp1 t
         ) t;
    

    提示:正如Gordon Linoff的回答所示,使用适当的软件(MySQL、Oracle、DB2等)和版本(例如,
    sql-server-2014
    )标记数据库问题是很有帮助的。语法和特征的差异通常会影响答案。