元のテーブルには、Timestamp with Intervalという列があります。
間隔:タイムスタンプ自体でソートした場合の、現在と以前のタイムスタンプの分単位の差
Timestamp Interval(InMinute)
2016-12-31 00:28:00 NULL
2016-12-31 00:29:00 1
2016-12-31 00:30:00 1
2016-12-31 00:45:00 15
2016-12-31 01:00:00 15
2016-12-31 01:15:00 15
2016-12-31 01:16:00 1
2016-12-31 01:17:00 1
2016-12-31 01:18:00 1
2016-12-31 01:19:00 1
T-SQLを使用して時間間隔の変化を検出し、出力を生成したい
StartDate EndDate Interval
2016-12-31 00:28:00 2016-12-31 00:30:00 1
2016-12-31 00:30:00 2016-12-31 01:15:00 15
2016-12-31 01:15:00 2016-12-31 01:19:00 1
インターバルが同じままだった期間を教えてください。 2番目の行は、2016-12-31 00:30:00
から2016-12-31 01:15:00
まで、間隔は同じ、つまり15であったことを示していますが、2016-12-31 01:15:00
の後で1に戻りました。
itzik Ben Gan(シーケンスのギャップとアイランド)の例があります。これは、この記事のベースです。 Gaps
DECLARE @vt_Source AS TABLE
( ts datetime NOT NULL PRIMARY KEY,
interval tinyint NULL
)
INSERT INTO @vt_Source(ts, interval)
VALUES('2016-12-31 00:28:00', NULL)
,('2016-12-31 00:29:00' , 1)
,('2016-12-31 00:30:00' , 1)
,('2016-12-31 00:45:00' , 15)
,('2016-12-31 01:00:00' , 15)
,('2016-12-31 01:15:00' , 15)
,('2016-12-31 01:16:00' , 1)
,('2016-12-31 01:17:00' , 1)
,('2016-12-31 01:18:00' , 1)
,('2016-12-31 01:19:00' , 1)
SELECT
min(ts_prev) AS startDate
,max(ts) AS endDate
,interval
FROM
(SELECT
ts
,interval
,ROW_NUMBER() OVER(ORDER BY ts ASC) AS rn_all
,ROW_NUMBER() OVER(PARTITION BY interval ORDER BY ts ASC) AS rn_group
,LAG(ts,1,ts) OVER(ORDER BY ts ASC) AS ts_prev
FROM
@vt_Source
)A
WHERE
A.interval IS NOT NULL
GROUP BY
rn_all - rn_group
,interval
ORDER BY
startDate ASC
このための出力:
startDate endDate interval
31/12/2016 00:28:00 31/12/2016 00:30:00 1
31/12/2016 00:30:00 31/12/2016 01:15:00 15
31/12/2016 01:15:00 31/12/2016 01:19:00 1
WHERE
句を追加して、最初の行(インターバル列にNULL
がある行)を削除しました
http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=fe1888d0a934d73de0ed9887aaf4d482
SQL Server 2012以降を使用している場合は、LEAD
関数も使用できます。
LEAD
は、関数のPARTITION BY
とORDER BY
に基づいて、次のレコードの列の値を取得します。このデータセット内では、何にも分割されていませんが、ts
値に基づいて並べています。
他の答えで一時テーブルを使用して、これを試してください:
DECLARE @vt_Source AS TABLE
( ts datetime NOT NULL PRIMARY KEY,
interval tinyint NULL
)
INSERT INTO @vt_Source(ts, interval)
VALUES('2016-12-31 00:28:00', NULL)
,('2016-12-31 00:29:00' , 1)
,('2016-12-31 00:30:00' , 1)
,('2016-12-31 00:45:00' , 15)
,('2016-12-31 01:00:00' , 15)
,('2016-12-31 01:15:00' , 15)
,('2016-12-31 01:16:00' , 1)
,('2016-12-31 01:17:00' , 1)
,('2016-12-31 01:18:00' , 1)
,('2016-12-31 01:19:00' , 1)
;WITH NextInterval AS (
SELECT
vs.ts
,vs.interval
,LEAD(vs.interval,1) OVER(ORDER BY vs.ts) AS next_interval
FROM @vt_Source AS vs
)
SELECT
ni.ts
,ni.next_interval AS interval
FROM NextInterval AS ni
WHERE ni.next_interval IS NOT NULL
AND ni.next_interval <> ISNULL(ni.interval,0)
ORDER BY ni.ts