クエリを作成しようとしています。連続した行のサブセット(ギャップとアイランド)の最小値と最大値を求める
入力は、 'name'の一意の値ごとに1から始まり、 'act'のエントリの指定されたシーケンスを定義する列 'rn'のrownumberによって順序付けられます。列 'act'では、複数の発生で> sleep <と> wake <の2つの値を保持します。目標は、starttとenddの最小値と最大値をそれらの値のいずれかの連続する各行のセットごとに見つけることです。
これは入力しなければならない:
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
所望の出力:
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
入力のソースがさらに列を提供しません。この例では、各サブセットのメンバー数が非常に高くなる可能性があります。
私はさまざまな集約方法を試しましたが、どれもうまくいきませんでした。私はLEAD
とLAGG
を使っていると信じています。そしてそれ以上のトリッキーは私をそこに連れていくかもしれませんが、それは非常に不愉快なようです。私は、各サブセットを区別すること、すなわち、そのすべてのメンバーに固有の識別子を作成することが重要であるという考えを持っている。これにより、min
とmax
の集約が簡単になります。たぶん私は間違っています。多分それは不可能です。多分自己結合。多分再帰的なcte。知りません。
だから誰でもこの方法を知っていますか?ヘルプは非常に感謝しています。
UPDATE:
ゴードン・リノフ、shawnt00とコメントし、他の貢献に感謝します。あなたの助言を得て、私はロジック閉鎖のツールボックスに大きなギャップを感じます。興味のために
:
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)
これはギャップと諸島の問題です。それを探して、解決策を見つけることができます。または、このページの第5章PDFを参照してください。https://www.manning.com/books/sql-server-mvp-deep-dives – mheptinstall
したがって、どのRDBMSですか? – Strawberry
enddとstarttの違いがグループ化されている場合は常に1ですか?または、これらのサンプルセットだけで、次のセットは名前の変更に基づいていますか? –