No tu wystarczy wyznaczyć początki przedziałów, a to będą wszystkie te rekordy (w ramach ticket), które poprzedzający error mają wcześniej o 10 lub więcej minut albo są pierwsze, jak to wiemy to łatwo sprawdzić granicę końca, czyli następny początek minus 1, na tej podstawie łatwo zrobić przedziały i po nich grupować:
Kopiuj
DECLARE @table1 TABLE
(
[Ticket] INT,
[ErrorCode] CHAR(1),
[Date] DATETIME
);
INSERT INTO @table1
VALUES
(1, 'A', convert(datetime,'01.07.2018 10:00:00',104)),
(1, 'B', convert(datetime,'01.07.2018 10:02:00',104)),
(1, 'C', convert(datetime,'01.07.2018 10:08:00',104)),
(1, 'A', convert(datetime,'01.07.2018 10:30:09',104)),
(1, 'B', convert(datetime,'01.07.2018 10:50:00',104)),
(1, 'D', convert(datetime,'01.07.2018 10:55:00',104)),
(1, 'D', convert(datetime,'01.07.2018 15:55:00',104)),
(1, 'D', convert(datetime,'02.07.2018 10:55:00',104)),
(2, 'A', convert(datetime,'20.10.2018 15:00:00',104)),
(2, 'C', convert(datetime,'20.10.2018 17:00:00',104)),
(2, 'C', convert(datetime,'20.10.2018 17:07:00',104)),
(2, 'A', convert(datetime,'21.10.2018 09:00:00',104));
; with dane as (
select
--kolumna numeru wiersz (można pominąć i użyć dla samego date)
row_number() over (partition by ticket order by date) r
--zwróci 1 jeżeli poprzednie zdarzenie jest starsze o 10 minut
,case when datediff(n,lag(date,1,dateadd(n,-11,date)) over (partition by ticket order by date),date) > 10 then 1 else 0 end AS b,
*
from
@table1
)
, p as (
select
ticket
--numer przedziału do grupowania
,row_number() over (partition by ticket order by r) Przedzial
--początek przedziału
,r [start]
--koniec przedziału
, lead(r,1,r+1) over (partition by ticket order by r)-1 [stop]
from
dane
where
--weż tylko początek przedziału
b=1
), result as (
select
d.Ticket
,p.przedzial
,d.errorcode
from
dane d
--pbierz informacje do ktorego predziału należy rekord
inner join p on p.Ticket=d.Ticket
and d.r between p.[start] and p.[stop]
)
select *
from result
W wyniku otrzymasz:
| Ticket |
przedzial |
errorcode |
| 1 |
1 |
A |
| 1 |
1 |
B |
| 1 |
1 |
C |
| 1 |
2 |
A |
| 1 |
3 |
B |
| 1 |
3 |
D |
| 1 |
4 |
D |
| 1 |
5 |
D |
| 2 |
1 |
A |
| 2 |
2 |
C |
| 2 |
2 |
C |
| 2 |
3 |
A |
Ja połączyć stringi w grupowaniu masz w swoim poprzednim temacie, dla sql- >= 2017 to będzie:
Kopiuj
select
ticket
,string_agg(errorcode,'/') errorcode
from
result
group by
ticket,przedzial
order by ticket,przedzial
Wynik:
| ticket |
errorcode |
| 1 |
A/B/C |
| 1 |
A |
| 1 |
B/D |
| 1 |
D |
| 1 |
D |
| 2 |
A |
| 2 |
C/C |
| 2 |
A |
P.S. Nie musisz pisać w postach jaka masz wersje, wystarczy odpowiedni tag do postu...