私のデータには、ID、ステータス、および時刻(hh:mm:ss)が含まれています。
すべての「場所」と「トンネル外」ステータスの間の合計時間を計算する必要があります
ID || time || Status
________________________________________________
1 || 08:09:14 || Out of Tunnel
2 || 08:10:59 || Location
3 || 08:11:42 || Out of Tunnel
4 || 08:11:55 || Location
5 || 08:16:36 || Location
6 || 09:41:36 || Location
7 || 09:43:10 || Out of Tunnel
8 || 09:43:19 || Location
「ロケーション」ステータスは、カウントを開始する必要がある場所を示します。次にステータスが「トンネル外」になったときにカウントを停止する必要があります。対応する「トンネル外」が指定されていない場合は、カウントしないでください。
次に、各合計を合計して総計を計算します。例えば:
______________________
| Total Time in Tunnel |
|______________________|
| |
| 01:32:11 |
|______________________|
ID 4で始まる2回目のラウンドのサンプルデータの時間は08:11:55なので、実際にそれが開始点として使用することになっている時間である場合、合計は01:31:58になります。とにかく、LAGおよびLEADウィンドウ関数を使用したソリューションを次に示します。計画でソートを防止する場合は、次のサポートインデックスを作成してください。
create unique index idx_time_status on dbo.t1(time, status);
2016以降で実行している場合は、次のダミーインデックスを作成してバッチ処理を有効にできます。
create nonclustered columnstore index idx_cs on dbo.t1(id) where id = -1 and id = -2;
SQL Server 2019より前では、SQL Serverは、クエリの参加テーブルの少なくとも1つに列ストアインデックスが存在しない場合、バッチ処理の使用を考慮しませんでした。このダミーインデックスを作成すると、それ自体では意味がなくても、ウィンドウ関数に対してより最適なバッチ処理を使用できます。インデックス付きとインデックスなしの両方のプランを確認してください。 詳細はこちら で説明します。
ソリューションコードは次のとおりです。
with c1 as
(
select *,
case
when status = 'location'
and lag(status) over(order by time) = 'location' then 'no'
else 'yes'
end as keeper
from dbo.t1
where status in ('location', 'out of tunnel')
),
c2 as
(
select *, lead(time) over(order by time) as nxt
from c1
where keeper = 'yes'
)
select dateadd(second, sum(datediff(second, time, nxt)), cast('00:00:00' as time(0))) as total
from c2
where status = 'location';
合計時間が24時間未満になると想定して、出力をTIMEとしてフォーマットしました。それ以上の可能性がある場合は、フォーマットロジックを少し追加するだけで済みます。
WITH cte AS (
SELECT t2.time - MIN(t1.time) delta
FROM test t1
JOIN test t2 ON t1.time < t2.time
AND t2.status = 'Out of Tunnel'
LEFT JOIN test t3 ON t1.time < t3.time
AND t3.time < t2.time
AND t3.status = 'Out of Tunnel'
WHERE t1.status = 'Location'
AND t3.id IS NULL
GROUP BY t2.time
)
SELECT SUM(delta) "Total Time in Tunnel"
FROM cte
唯一の欠陥-сonverttime
フィールドは、自分で比較可能で減算可能で合計可能なデータフォーム/タイプ(または適切な場所で適切な関数を使用)に対応しています。