SQL Server Group by Value!=没有Cursor循环的前一个值

时间:2015-12-24 03:46:39

标签: sql-server performance tsql group-by

我必须写一个T-SQL来获得超速行(最大/最小/平均),但条件是如果任何行< speedvalue然后将显示新的超速行

(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

我的计划是使用以下

  1. 循环行,如果当前!= prev且prev = 0则为新的超速值
  2. 如果current = prev且prev = 1则当前的overspeedrowid = prev overspeedrowid
  3. 通过overspeedrowid从计算的表格最小/最大组中选择
  4. 所以计算的表格必须像这样

    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
    
    • 我尝试了一个光标,但由于生产数据约为2,000,000行,因此需要很长时间。

    • 我尝试使用连接第1行Update并将第1行与当前第1行进行比较,但未更正,因为它只更新了第二行

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

    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)
    

1 个答案:

答案 0 :(得分:2)

在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;