(PostgreSQL 8.4)前の例を続けて、ウィンドウ関数を使用したギャップとアイランドの処理についてさらに理解を深めたいと思います。次の表とデータを検討してください。
CREATE TABLE T1
(
id SERIAL PRIMARY KEY,
val INT, -- some device
status INT -- 0=OFF, 1=ON
);
INSERT INTO T1 (val, status) VALUES (10, 0);
INSERT INTO T1 (val, status) VALUES (11, 0);
INSERT INTO T1 (val, status) VALUES (11, 1);
INSERT INTO T1 (val, status) VALUES (10, 1);
INSERT INTO T1 (val, status) VALUES (11, 0);
INSERT INTO T1 (val, status) VALUES (10, 0);
前に説明したように、デバイスはオンとオフを切り替えます。今回は特定のシーケンスを抽出したいと思います。
- 重複していないすべての新しい
ON
ステータスレコードを表示します(同じデバイスを2回続けて表示します) - 現在のデバイスから適切な
OFF
ステータスを表示するON
私が得ることができる最も近いものはこれです:
SELECT * FROM (
SELECT *
,lag(val, 1, 0) OVER (PARTITION BY status ORDER BY id) last_val
,lag(status, 1, -1) OVER (PARTITION BY val ORDER BY id) last_status
FROM t1
) x
WHERE (last_val <> val OR last_status <> status)
AND (status = 1 OR last_status <> -1)
ORDER BY id
これにより、サンプルに含まれていないより多くの偽のデータが除外されますが、基本的には、後続の重複(ステータスに関係なく)とOFF
一致しない上位レコードを削除することです。レコード、、、3
が返されますが4
、5番目は必要ありません。新しいの後に来たものです。そのため、そのギャップを飛び越えて、現在アクティブなデバイスに適した次のデバイスを探す必要があります。5
6
OFF
ON
OFF
- 10がオフになります-このコンテキストでは偽物ですが、lag()を台無しにします
- 11がオフになります-このコンテキストでは偽物ですが、lag()を台無しにします
- 11がオンになります-OK、新しいシーケンス、SELECTに含めます
- 10がオンになります-OK、新しいシーケンス、SELECTに含める
- 11がオフになります-メッセージが遅れて届きました。ギャップを無視する必要があります
- 10がオフになります-OK、行4に対して適切なオフ、SELECTに含める必要があります
適切にフィルタリングされたら、その上で次の行のID(タイムスタンプを想像してください)を取得し、ステータスlead()
ではないすべてのレコードを除外したいと思います。ON
これには3つの埋め込みSELECTステートメントが必要になると思います。ON
これにより、別の状態または適切な回転の状態になるまで、デバイスがアクティブであった期間を明確に理解できますOFF
。