回答

收藏

根据sql server中的相关值进行数据分组

技术问答 技术问答 93 人阅读 | 0 人回复 | 2023-09-13

数据间隔为15分钟:# C* f5 l( O- H9 b. ?  e; S, }
时间值4 N; R/ `3 M  `) @0 R
2010-01-01 00:15 3
* V9 S, g+ G& @- n0 B2010-01-01 00:30 2' U- U, I7 G8 K! `6 s, Y
2010-01-01 00:45 4
4 ?: D7 X( j! h: \9 K' G0 |4 V  |2010-01-01 01:00 5
5 D9 q8 |3 r4 o( `9 ]3 F" G1 @2010-01-01 01:15 1
$ J5 M$ d. ~1 L6 [- s8 _2010-01-01 01:30 3
+ A0 y4 ]; d1 x2010-01-01 01:45 4
+ X* t* x6 b9 z7 n# k. z' x2010-01-01 02:00 12
6 o$ \( A2 V, m# p0 k" v& C8 l2010-01-01 02:15 13/ ?4 ~3 M# i& k2 L% g3 C
2010-01-01 02:30 12
* S) i. s- X6 i+ x2010-01-01 02:45 144 \/ J* B9 \. _$ ]$ I
2010-01-01 03:00 156 J2 Z  y/ q: Y/ F; s
2010-01-01 03:15 3- O. `9 c" L7 G4 f; u
2010-01-01 03:30 2  F1 t' e- `2 g. c; e+ m" L3 T
2010-01-01 03:45 3
- X' \" w( o2 O9 A1 e( z2010-01-01 04:00 5
$ \  l, }; P3 |% h+ u.....
2 N2 K# C0 L+ N1 X$ Z.....
+ L% _- ^- l% \- w- \+ r.....
! I8 `3 ^6 S; f6 z2010-01-02 00:00
2 j# k, S9 i+ R5 _6 }1 M通常会有96分。/ h  {6 s5 J4 a: p
根据这些值,我们可能会注意到从00:15到01:45的值彼此接近,从02:00到03:00的值彼此接近,而从03:15到04:00他们彼此靠近。
; `, _: u# ~, r基于“彼此靠近”规则,我希望将数据“分为”三个部分:
# E$ d0 _" I! D* L8 z00:15至01:45' ?) I/ }9 {/ p
02:00至03:00
6 ]; K  _$ t& F- p( v03:15至04:007 C: s2 F; u" a* G$ s% X

5 f* x, Z4 W/ F请注意,数据可以是随机数据,并且可以根据上述规则分为3个以上的部分,但最大值不能超过10个部分。并且分组必须遵循时间顺序,例如,您不能将00:15/02:30/04:45分为1组,因为这3点不是连续的。8 M/ D- a& I. q, |
请考虑一下如何在t-sql中实现它。
* c9 x8 A% q9 H# f已更新: 值可能是:
" s: }( W$ X, ^6 z, E% R$ a时间值* d% m9 b6 O/ G- r; N% m
2010-01-01 00:15 3
; F. R7 Q  m! Y, T$ t2010-01-01 00:30 2
1 d$ l4 N- [; y- [* w2010-01-01 00:45 4
. G; p/ m8 _$ P/ D7 B2010-01-01 01:00 5
2 {) ^: y% k0 h8 B7 _2 _5 T2010-01-01 01:15 1
$ i  z9 r& t- a* x2010-01-01 01:30 3
& F( e) d. y% w' o2010-01-01 01:45 4# z& g  x/ F% P9 r4 C
2010-01-01 02:00 128 d8 A( r/ i' D$ x) a7 M$ c
2010-01-01 02:15 13( g7 Q# s! b% s/ ^- m
2010-01-01 02:30 4-突然减少
- U- S4 x6 i) _2010-01-01 02:45 14
% W$ v  ^- O$ w! m$ p+ ?2010-01-01 03:00 15
+ h% s' m' k0 O' U2 W6 \' \2010-01-01 03:15 3
5 o) X2 p% Y% U% |* C3 p7 [  g8 f2010-01-01 03:30 2& Q0 V- M  ^2 o: S
2010-01-01 03:45 3: }: X" k/ h$ H1 |" n& s; E, M
2010-01-01 04:00 5, ~: c. }2 ~* e8 g: e
.....5 f! l3 f3 o% f( S6 g+ w3 I1 j. G; A
.....
# ?3 S; o; Q9 b6 d1 I% t.....6 H8 y% j3 C8 M" n& E
2010-01-02 00:00
3 X% {) @, V" U, e对于这种情况,我们不应该将02:30单独分组,因为我们希望组的大小必须至少为3分,并将该点(02:30)放到上一个分组(从02:00到03:00)。
2 M' L/ b* z6 \               
0 X; C, L) g: ^) n$ S* \$ r解决方案:
& c# C/ o2 E5 w0 F$ w                % n: ~1 \6 {' Y% \& z1 k

2 ~6 a' l( ?. R* ?2 g8 o  G1 h# l! R9 O' O6 {1 l
                由于您的问题发生了很大的变化,因此这里是新问题的新答案,我只包含了代码部分。: l2 |& B& ]0 h. r+ W+ @0 c
declare @t table(time datetime, value int)- d5 z. J: l  n; k
declare @variation float
  J/ [( M3 F' r) [5 D# ?5 e" q4 Yset @variation = 2. A: ]4 `$ ?) D3 `/ R
set nocount on  U7 d# e$ ^1 E- g+ e
insert @t values('2010-01-01 00:15',3)- a  K: W7 t+ Q, \- e+ f
insert @t values('2010-01-01 00:30',2)2 M6 I* v  [6 J7 Y! s0 B
insert @t values('2010-01-01 00:45',4)
0 Q0 `6 {2 y- {' [( ?0 Ainsert @t values('2010-01-01 01:00',5)
* S' l# z7 l1 w8 w( j- p- @insert @t values('2010-01-01 01:15',1)& R; q7 O9 `$ ]& {
insert @t values('2010-01-01 01:30',3)
% {  }6 {! R) w9 y2 t- `# Q& [: Qinsert @t values('2010-01-01 01:45',4)) g& L$ ^1 H. O3 _! Z4 o
insert @t values('2010-01-01 02:00',52), r, ?; f) s2 ~- U' T& f) r& z
insert @t values('2010-01-01 02:15',5)
; ~: Q# s* _- r4 G6 H" yinsert @t values('2010-01-01 02:30',52)  w! J: V0 T2 I6 y* Q! K  D
insert @t values('2010-01-01 02:45',54)9 Z, I/ s8 [  z# w- j" \
insert @t values('2010-01-01 03:00',55)
3 Z% `2 u- s; Z' B; R/ C! Hinsert @t values('2010-01-01 03:15',3)  J- g8 ?- i' F7 ~9 o4 K
insert @t values('2010-01-01 03:30',2)
( `( Y$ v9 M2 ?8 Y4 n; vinsert @t values('2010-01-01 03:45',3)% X  q. z8 O/ p4 k
insert @t values('2010-01-01 04:00',5); \$ F7 W2 }2 ~6 G

' M' l5 x- o3 _. a1 }1 kdeclare @result table(mintime datetime, maxtime datetime)6 ?1 c% G  ?$ H/ S) c  C) X
a:
! H, ?) o* M% ^9 R" a6 x! tdelete @result
/ w- M2 V: p1 t9 I;with t as
$ H0 M4 P, v$ r: {" U* H(
- m, M* e5 d* y* f, U6 P- p8 Zselect *, rn = row_number() over(order by time), log(value) lv from @t where datediff(day, time, '2010-01-01') = 02 r& v, O, s. D" q
), a as4 t- x2 M. ?' B9 d: E) ?7 P
() X% p9 n3 z! E' s
select time, lv, rn, 0 grp from t where rn = 1
" d, C" S, o* ^3 a' Xunion all
" P8 c  U' j: [# aselect t1.time, a.lv, t1.rn,
9 ~, i3 G6 V. x0 a7 ^8 L! Hcase when exists (select 1 from t t2 where t1.rn between rn + 1 and rn + 3 and
8 G# K1 M& n  F1 o( C  I! Blv between t1.lv - @variation and t1.lv +@variation) then grp else grp + 1 end
8 A% L. |( j6 O& F' L( rfrom t t1 join a on
& |6 |. E6 v& Y5 X9 K6 bt1.rn = a.rn +1
) b4 i3 l0 g' M) M)
- d# x% P) L6 c, binsert @result
) J) f$ A) x& i; q6 L+ Q. dselect min(time), max(time) from a group by grp! R- J: A/ r# a7 z# |8 t4 D
if @@rowcount > 10
9 l; p$ o5 S! X# k+ @% y# nbegin
2 m3 I+ O9 Y+ H$ |    set @variation=@variation + .5 * @! k! N# F% }' h- ~+ q
    goto a
: K/ S" B7 R$ o! Gend
+ K* d$ [( S' R; Z$ c! |0 Xselect * from @result
0 i; L  G6 d# A结果:
: y3 W- h) C( }mintime                     maxtime
" Z* I2 y) S3 m2 T; e2010-01-01 00:15:00.000     2010-01-01 01:45:00.000
4 p5 X) Y8 t5 c3 c2 ?2010-01-01 02:00:00.000     2010-01-01 03:00:00.0005 o, i. t% \+ A$ Z" ~2 ]9 _7 ?, P0 y/ k
2010-01-01 03:15:00.000     2010-01-01 04:00:00.000
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则