2017-08-30 3 views
1

私はこのようなテーブルの一部を持っている:それはの50ミリ秒以内だWHERE句は、タイムスタンプが50msの行を選択しないために使用しますか?

元の表の2行目が削除されていた
timestamp     | Source 
----------------------------+---------- 
2017-07-28 14:20:28.757464 | Stream 
2017-07-28 14:20:29.777678 | Poll 
2017-07-28 14:21:28.582532 | Stream 

ので:

timestamp     | Source 
----------------------------+---------- 
2017-07-28 14:20:28.757464 | Stream 
2017-07-28 14:20:28.775248 | Poll 
2017-07-28 14:20:29.777678 | Poll 
2017-07-28 14:21:28.582532 | Stream 

が、私はこれを実現したいですその前または後のタイムスタンプ。重要なのは、Source = 'Poll'の場合のみ行を削除することです。

これはWHERE句でどのように実現できるのかわかりませんか?

ご協力いただきありがとうございます。

+0

行に3つのPoll行があり、3つすべてがタイムスタンプから50ms以内にある場合はどうなりますか? –

+0

3つの投票、お互いから50未満、まだ3番目の投票はストリームから51、次に何ですか? –

+0

ポーラーは50msよりも長い時間に設定されるため、これはデータ内では起こりません。ストリームデータは、ポーリングから50ミリ秒以内にしか存在しません。 – Harry

答えて

0

私たちは何をしていても、それをプールに限定してから、それらの行をStreamsと結合することができます。

with 
streams as (
select * 
from test 
where Source = 'Stream' 
), 
pools as (
    ... 
) 

(select * from pools) union (select * from streams) order by timestamp 

プールを取得するには、さまざまなオプションがあります:行ごとに

相関サブクエリ

我々はそこに行のみを選択し、同じソースで前の行を取得するために余分なクエリを実行します以前のタイムスタンプ(最初の行)がないか、以前のタイムスタンプが50ms以上古い場合です。

with 
... 
pools_with_prev as (
    -- use correlated subquery 
    select 
    timestamp, Source, 
    timestamp - interval '00:00:00.05' 
     as timestamp_prev_limit, 
    (select max(t2.timestamp)from test as t2 
     where t2.timestamp < test.timestamp and 
    t2.Source = test.Source) 
     as timestamp_prev 
    from test 
), 
pools as (
    select timestamp, Source 
    from pools_with_prev 
    -- then select rows which are >50ms apart 
    where timestamp_prev is NULL or 
    timestamp_prev < timestamp_prev_limit 
) 

... 

https://www.db-fiddle.com/f/iVgSkvTVpqjNZ5F5RZVSd2/2

2つのスライドテーブル代わ​​りに、各行について、サブクエリを実行している

に参加し、私たちは私たちのテーブルのコピーを作成し、各プールの行は前の行と結合ので、それをスライドさせることができます同じソースタイプ。

with 
... 
pools_rn as (
-- add extra row number column 
-- rows: 1, 2, 3 
select *, 
    row_number() over (order by timestamp) as rn 
from test 
where Source = 'Pool' 
), 
pools_rn_prev as (
-- add extra row number column increased by one 
-- like sliding a copy of the table one row down 
-- rows: 2, 3, 4 
select timestamp as timestamp_prev, 
    row_number() over (order by timestamp)+1 as rn 
from test 
where Source = 'Pool' 
), 
pools as (
-- now join prev two tables on this column 
-- each row will join with its predecessor 
select timestamp, source 
from pools_rn 
    left outer join pools_rn_prev 
    on pools_rn.rn = pools_rn_prev.rn 
where 
    -- then select rows which are >50ms apart 
    timestamp_prev is null or 
    timestamp - interval '00:00:00.05' > timestamp_prev 
) 

... 

https://www.db-fiddle.com/f/gXmSxbqkrxpvksE8Q4ogEU/2

スライディングウィンドウ

現代のSQLは、前の行と結合するためにスライディングウィンドウを使用して、ソースによってパーティショニングと同様のものを行うことができます。

with 
... 
pools_with_prev as (
    -- use sliding window to join prev timestamp 
    select *, 
    timestamp - interval '00:00:00.05' 
     as timestamp_prev_limit, 
    lag(timestamp) over(
     partition by Source order by timestamp 
    ) as timestamp_prev 
    from test 
), 
pools as (
    select timestamp, Source 
    from pools_with_prev 
    -- then select rows which are >50ms apart 
    where timestamp_prev is NULL or 
    timestamp_prev < timestamp_prev_limit 
) 


... 

https://www.db-fiddle.com/f/8KfTyqRBU62SFSoiZfpu6Q/1

私は、これが最適であると考えています。

関連する問題