回答

收藏

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

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

数据间隔为15分钟:
/ M! Y' S3 F! d. d1 f9 E时间值% ^* }  k* D  ?" f. F: w3 t
2010-01-01 00:15 36 m, a0 D$ O* \4 A! w
2010-01-01 00:30 2  h" m, B7 {' d+ n$ v4 L
2010-01-01 00:45 4
, j. G1 ?% N; K: b6 l2010-01-01 01:00 5
: D- d' J% d. Y& `2 w2010-01-01 01:15 15 _$ Y: h% F6 o, s
2010-01-01 01:30 3+ [& b2 p* O( _% ?; F
2010-01-01 01:45 4" u1 H8 D8 I; H( R+ Z6 O
2010-01-01 02:00 123 U6 {& W0 p5 Z5 @
2010-01-01 02:15 134 B0 s- w. t% a) a/ ^! Q: D
2010-01-01 02:30 12
9 d* o% p. I- i$ h2010-01-01 02:45 140 c6 t3 D( J2 |# q3 G8 G' ]% ]
2010-01-01 03:00 15
% f/ W: {$ X5 A, Z, b2010-01-01 03:15 3
. q! e2 i% `; [2010-01-01 03:30 2
9 K4 ^' }% T7 B% V2010-01-01 03:45 32 D, {7 ]7 Q. u6 L' [$ u  K( Z( P
2010-01-01 04:00 5
& U9 C% O/ D- S2 E0 T: v4 {7 K- s.....
: L- D6 D5 x) S.....
% o' b+ r7 J; |% y.....; I5 i& E3 z9 d# Y; k3 [
2010-01-02 00:00
) @5 G* _1 X. ^通常会有96分。: Z" o7 {6 B9 M1 b  ]( E! o
根据这些值,我们可能会注意到从00:15到01:45的值彼此接近,从02:00到03:00的值彼此接近,而从03:15到04:00他们彼此靠近。6 _5 x' B) V& J  H
基于“彼此靠近”规则,我希望将数据“分为”三个部分:8 {. ^$ W/ A' Q% e1 k4 v6 C
00:15至01:453 o; f* h* c: }  _! O
02:00至03:00
6 V$ g& \2 D2 K, Y6 ^3 S, u03:15至04:001 a8 A& x+ Q) _% l

1 \$ E; a8 Z' S. k1 g请注意,数据可以是随机数据,并且可以根据上述规则分为3个以上的部分,但最大值不能超过10个部分。并且分组必须遵循时间顺序,例如,您不能将00:15/02:30/04:45分为1组,因为这3点不是连续的。
& \  G; t. `2 K) z( B6 y请考虑一下如何在t-sql中实现它。6 R, A. Q( {* T% v, F- P4 G
已更新: 值可能是:
2 W+ [6 C3 i+ q8 j7 |. k5 ^, D5 N' `5 H时间值
) h! W2 h3 ^8 C1 j0 h% R2010-01-01 00:15 3
% F7 z+ a7 C; ]; M; ^2 X! U5 q6 U2010-01-01 00:30 29 m" i: d, D4 H
2010-01-01 00:45 4; G% G7 j1 u' B/ H- y
2010-01-01 01:00 5' @9 h+ a; E: W2 ~7 p
2010-01-01 01:15 1% i2 e! B+ ]- j7 y* K+ d
2010-01-01 01:30 3" y2 }- M4 X7 ?, i
2010-01-01 01:45 43 I5 b3 e+ U, W) }9 g
2010-01-01 02:00 12. }+ P  @0 v" h  C; I% Z! _! K8 v) y
2010-01-01 02:15 13+ l  z# o0 O9 a
2010-01-01 02:30 4-突然减少
/ ]! e% @8 N! R8 [2010-01-01 02:45 14) e6 c4 Z) N1 r
2010-01-01 03:00 151 Q' w8 D2 k& i: |0 ^) k, a0 k
2010-01-01 03:15 36 }+ c0 u7 @. q2 g" V7 K4 g
2010-01-01 03:30 2
5 x1 R" T6 M4 B1 R* q2010-01-01 03:45 3
" x- t) X! ?5 H7 S5 Z2 ?1 \2010-01-01 04:00 5
; z6 S/ p5 V3 u9 ~) C6 P3 q2 ~.....9 h9 l# |7 }  ^' V- w
.....# @% X( }* \; `- f( E- Z9 R
.....
  }& v/ W# t. f# N4 _0 A2010-01-02 00:00
2 @% j$ P; C! J对于这种情况,我们不应该将02:30单独分组,因为我们希望组的大小必须至少为3分,并将该点(02:30)放到上一个分组(从02:00到03:00)。4 I/ s1 ^' @' z6 Y% z7 C2 H
                4 D- e( X5 @/ K/ t
解决方案:2 Z5 ?1 p: c! g' H% {
                ! I1 ~! {& L/ C0 c* c  b  X. P6 Y
8 V. I' Y: u# K+ ^  u, z: I

7 i4 F# V- V: H  W                由于您的问题发生了很大的变化,因此这里是新问题的新答案,我只包含了代码部分。. U: ?- G) q, P% x
declare @t table(time datetime, value int)1 \4 P% ~9 v% S. v* `7 Q2 G) {
declare @variation float
+ l) Y' r7 P8 {- U& `8 M  n9 |set @variation = 2
# p/ r# b  m" a6 {set nocount on/ J" ]) V/ f/ B1 _$ h
insert @t values('2010-01-01 00:15',3)
) E9 s6 H4 a! @  g7 o+ @6 ]insert @t values('2010-01-01 00:30',2)8 u% G. C1 r: r5 [) a" o
insert @t values('2010-01-01 00:45',4)
9 p  e, c# o) T; b0 u+ g, ~, \insert @t values('2010-01-01 01:00',5), d1 a$ n9 Q$ h, {2 Q4 B& t
insert @t values('2010-01-01 01:15',1)
, H2 \5 R& w! P1 Vinsert @t values('2010-01-01 01:30',3)
) z$ ~: t5 L: S% D& R8 k1 Ninsert @t values('2010-01-01 01:45',4)
' s$ n' }# w6 T- r" V' ^& xinsert @t values('2010-01-01 02:00',52)
8 H" c+ v0 g( ?9 X+ finsert @t values('2010-01-01 02:15',5)
+ O' c% p9 x. @" Z4 d% t8 P- yinsert @t values('2010-01-01 02:30',52)9 i$ q, D7 f5 q
insert @t values('2010-01-01 02:45',54)6 R6 _4 Z6 f0 J
insert @t values('2010-01-01 03:00',55)/ i# `- i' n5 {' h) l
insert @t values('2010-01-01 03:15',3)- {* N& k+ e, C6 L" a% r) E
insert @t values('2010-01-01 03:30',2)
$ f9 S# J) l: w8 C7 @1 s; Winsert @t values('2010-01-01 03:45',3)6 g) [$ s2 d9 _, U9 l1 ?+ s. Z2 Y
insert @t values('2010-01-01 04:00',5)4 }7 ?' W0 B5 n* ^) j" o
! [. U8 e4 q# k& c
declare @result table(mintime datetime, maxtime datetime)
$ R4 f& ?1 R7 |6 \& E$ ia:! ~$ Q  E6 Q. d; _7 l
delete @result
, d0 c9 y1 h$ E: z;with t as3 b* `1 a/ g+ J0 h3 w4 W5 m
(
% M7 w4 J3 d; {; k  Zselect *, rn = row_number() over(order by time), log(value) lv from @t where datediff(day, time, '2010-01-01') = 0
' V, [; M0 G% n/ C0 c/ [1 q), a as" N  x% x8 Y" p* O: J
(4 m' e+ e" V5 V/ P
select time, lv, rn, 0 grp from t where rn = 1
* W$ Y; I9 a$ Eunion all$ o. c9 z# _6 c" L2 r# m
select t1.time, a.lv, t1.rn, 9 X; C- Z% K' V) Y# }. u2 P" n
case when exists (select 1 from t t2 where t1.rn between rn + 1 and rn + 3 and
, {( N# a. D7 Dlv between t1.lv - @variation and t1.lv +@variation) then grp else grp + 1 end
* d" c0 w4 Y$ K" ], {# O  E  Mfrom t t1 join a on 3 M' Y- U& Z0 j; i  A
t1.rn = a.rn +1' ]5 J+ t- |8 h
)+ V+ ?9 o; q* b5 [: o! M) _
insert @result# }9 v- I. z1 i5 y
select min(time), max(time) from a group by grp
8 |/ Q8 g0 _: {+ k: D5 ~9 z4 dif @@rowcount > 10 ' V; Y3 n1 j1 E* f& G" \) E
begin . p5 Y1 J4 J* I
    set @variation=@variation + .5 " n7 `2 G1 n. u) D
    goto a
9 U- R) m0 }2 f( u) Gend& T# o* `+ a. I6 T: Q
select * from @result& r7 T# }8 o+ F. e* q0 r: k
结果:6 @4 K9 r4 B- Y3 ^: V- t$ f. e
mintime                     maxtime; b3 e7 ^/ p7 @4 G' ]* ]
2010-01-01 00:15:00.000     2010-01-01 01:45:00.000+ T; \$ \- G4 B" G
2010-01-01 02:00:00.000     2010-01-01 03:00:00.000
+ B$ e6 b) ?. G8 Z2010-01-01 03:15:00.000     2010-01-01 04:00:00.000
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则