回答

收藏

考虑行之间的“差异”对行进行分组

技术问答 技术问答 213 人阅读 | 0 人回复 | 2023-09-14

我有一个表,其中包含开始时间(在示例中使用数字以使其保持简单)以及事件的持续时间。
" m1 y; Z8 o7 ]* P3 k. i: n我想确定“块”及其开始时间和结束时间。
. o9 v. B& S9 A! b0 g+ V+ g每当前一行的结束时间(开始时间+持续时间)(按开始时间排序)与当前行的开始时间之间的差值为时,>=5应开始一个新的“块”。
- ^) Z- a* g/ j这是我的测试数据,包括在注释中尝试进行图形解释的尝试:
" y( ?( J* X+ gWITH test_data AS (% k; J* W" `# V" A; Q
  SELECT  0 s, 2 dur FROM dual UNION ALL   --# 鈻犫枲
% T2 f9 q% o9 d0 b2 w" r' e  SELECT  2  , 2     FROM dual UNION ALL   --#   鈻犫枲2 C+ H  p, X  z! D. \7 |# i! @% q  [
  SELECT 10  , 1     FROM dual UNION ALL   --#           鈻?  e7 T6 J5 }+ o  B
  SELECT 13  , 4     FROM dual UNION ALL   --#              鈻犫枲鈻犫枲1 \0 A  L( p: {. W  D* o7 ~
  SELECT 15  , 4     FROM dual             --#                鈻犫枲鈻犫枲( R$ }2 P, Z# E4 k
)2 u+ d, f1 l4 i- }: C/ V
--# Should return
  t( y& ^# F0 [0 [) m% L+ u. z--#   0 ..  4                              --# 鈻犫枲鈻犫枲# o4 B2 f% f6 I1 ^
--#  10 .. 19                              --#           鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻?/ g8 |5 D& o" }, x
第一个块开始于0,结束于4。由于与下一行的区别是>=5,开始另一个块10,终止于19。; {! C% L- F$ G

9 M6 q6 [7 m1 K: U1 u我可以使用来识别块的第一行LAG,但是我还没有找到如何继续的方法。
1 x# x2 J/ b* p  |我可以在PL / SQL循环中解决问题,但是出于性能原因,我试图避免这种情况。0 w9 q. {" `7 Q5 R3 r7 K5 K

7 v' t1 J& A2 X) E- |关于如何编写此查询的任何建议?( L: y' P. V& V! d  w' d
预先感谢,彼得/ \) p7 a8 d! b8 b" E% c
               
* ^0 {9 ~6 ^2 u( _6 d* G8 }8 o解决方案:
7 ]: N: @8 ~/ x* b- H6 I5 Z                + G8 q+ _1 ]) C8 H) Y8 t6 J
- L& m1 c! b+ k- F7 O# A) h

% ?( J. q) @( q! u. T/ `+ R0 `% N                我将子查询与分析结合使用,以识别和分组连续范围:
+ V2 P. e8 Z" q5 z" {1 {* MSQL> WITH test_data AS (: h- V* x4 Y# \1 d* Y1 Z
  2    SELECT  0 s, 2 dur FROM dual UNION ALL   --# 鈻犫枲) ~- H9 b4 n% j  Y* Q) N3 X
  3    SELECT  2  , 2     FROM dual UNION ALL   --#   鈻犫枲% E* h3 p/ M0 u2 u
  4    SELECT 10  , 1     FROM dual UNION ALL   --#           鈻?
0 v, Z% m  J  p. I( G  5    SELECT 13  , 4     FROM dual UNION ALL   --#              鈻犫枲鈻犫枲
9 _3 p. Y: D" b* O# W( s# ?2 V4 ~  6    SELECT 15  , 4     FROM dual             --#                鈻犫枲鈻犫枲
; B3 y' H% i/ X* h  7  )4 X1 _; |! s' a% E$ J
  8  SELECT MIN(s) "begin", MAX(s + dur) "end"
/ I+ M; N$ ~! y  9    FROM (SELECT s, dur, SUM(gap) over(ORDER BY s) my_group7 ]% Q) U6 }( I7 M5 [
10             FROM (SELECT s, dur,8 B6 b+ A, E4 |: A
11                           CASE& d5 I6 X) Y# M7 O4 V% X% I: G" O9 x! A
12                              WHEN lag(s + dur) over(ORDER BY s) >= s - 5 THEN0 U, d& I8 l: Q! o9 P, b$ u; _0 k
13                               0
; G) R( l  P( I 14                              ELSE8 Z/ t. s  V4 U1 l8 S% r1 ~
15                               17 F- L3 }# y2 U. {7 x3 V# A7 @
16                           END gap) D2 H  V8 G8 l. U4 m; u
17                      FROM test_data4 O. x  a2 r+ q9 b$ Z1 e4 t
18                     ORDER BY s))
" N# c7 ^3 u, q  N* n 19   GROUP BY my_group;
5 t% y7 _  [. {7 ~8 I     begin        end4 @. t  o( i( z& K' t
---------- ----------+ k, c% ^8 d3 D; S) t' S( h' ]" p
         0          4$ a  Z; q1 O8 u7 @
        10         19
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则