Versuchen, eine Abfrage zu erstellen.Finden Sie Min und Max für Teilmengen von aufeinanderfolgenden Zeilen - Lücken und Inseln
Die Eingabe wird nach Zeilennummer in Spalte 'rn' sortiert, beginnend mit 1 für jeden eindeutigen Wert in 'name' und definiert eine bestimmte Sequenz von Einträgen in 'act'. In der Spalte 'act' hält es zwei Werte in mehreren Vorkommen,> schlafen < und> wecken <. Das Ziel besteht darin, für jeden aufeinanderfolgenden Satz von Zeilen eines dieser Werte den minimalen und maximalen Wert von startt und ended zu finden.
Dies ist der Eingang sein:
name act rn startt endd
---------- ---------- ------ ------ ------
jimmy sleep 1 1 3
jimmy wake 2 4 7
jimmy wake 3 8 10
jimmy sleep 4 11 13
karen wake 1 1 4
karen sleep 2 5 7
karen wake 3 8 9
karen wake 4 10 12
karen wake 5 13 14
karen sleep 6 15 17
karen sleep 7 18 20
der gewünschte Ausgang:
name act startt endd
---------- ---------- ------ ------
jimmy sleep 1 3
jimmy wake 4 10
jimmy sleep 11 13
karen wake 1 4
karen sleep 5 7
karen wake 8 14
karen sleep 15 20
Die Quelle des Eingangs bietet keine weiteren Spalten. Die Anzahl der Mitglieder in jeder Teilmenge kann sehr viel höher sein als in diesem Beispiel.
Ich habe verschiedene Arten der Aggregation versucht, aber keine funktionierte. Ich glaube, mit LEAD
und LAGG
und weitere Tricks kann mich dorthin bringen, aber das scheint schrecklich unelegant. Ich habe den Gedanken, dass es der Schlüssel ist, jede Teilmenge zu unterscheiden, d. H. Einen Identifizierer zu erzeugen, der für alle seine Mitglieder einzigartig ist. Mit diesem ist ein Aggregat mit min
und max
einfach. Vielleicht bin ich falsch. Vielleicht ist es unmöglich. Vielleicht ein Self-Join. Vielleicht eine rekursive Cte. Ich weiß es nicht.
Also: weiß jemand, wie man das bekommt? Hilfe wird sehr geschätzt.
UPDATE:
Danke zu Gordon Linoff, shawnt00 und den anderen Mitwirkenden, die kommentiert. Mit Ihrem Rat habe ich große Lücken in meinem Werkzeugkasten der Logik geschlossen.
für alle Interessenten:
declare @t table (
name nvarchar(10)
,act nvarchar (10)
,startt smallint
,endd smallint
)
insert into @t (
name
,act
,startt
,endd
)
values
('jimmy','sleep', 1,3)
,('jimmy','wake', 4,7)
,('jimmy','wake', 8,10)
,('jimmy','sleep', 11,13)
,('karen','wake', 1,4)
,('karen','sleep', 5,7)
,('karen','wake', 8,9)
,('karen','wake', 10,12)
,('karen','wake', 13,14)
,('karen','sleep', 15,17)
,('karen','sleep', 18,20)
; --- all rows, no aggregating
with
cte as (
select
name
,act
,row_number() over (partition by name order by name,startt) rn
,row_number() over (partition by name, act order by name,startt) act_n
,startt
,endd
from
@t)
select
name
,act
,startt
,endd
,rn
,act_n
,rn - act_n diff
from
cte
order by
name
,rn
;--- aggregating for the desired ouput
with
cte as (
select
name
,act
,row_number() over (partition by name order by name,startt) rn
,row_number() over (partition by name, act order by name,startt) act_n
,startt
,endd
from
@t)
select
name
,act
,min(startt) startt
,max(endd) endd
,min(rn) min_rn
,max(rn) max_rn
from
cte
group by
name
,act
,rn - act_n
order by
name
,min(rn)
Dies ist ein Gaps and Islands-Problem, suchen Sie danach und Sie finden Lösungsvorschläge. Oder sehen Sie sich das Kapitel 5 PDF auf dieser Seite an https://www.manning.com/books/sql-server-mvp-deep-dives – mheptinstall
Also, welches RDBMS? – Strawberry
Wenn der Unterschied zwischen Ende und Start immer 1 ist, wenn sie zusammen gruppiert werden sollen? Oder sind das nur Beispielsätze und der nächste Satz basiert auf den Namensänderungen, act? –