|
我有一个表,其中包含开始时间(在示例中使用数字以使其保持简单)以及事件的持续时间。
" 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 |
|