1

100 ミリ秒以内に行われたリクエストを表示する postgresql のクエリを作成する必要があります。postgresql テーブル リクエストには、リクエスト ID (request_id) とタイムスタンプ (create_stamp) があります。

以下の Mu クエリは機能しますが、非常に低速です。

select
    b1.create_stamp as st1,
    b2.create_stamp as st2,
    b1.request_id as b1_id,
    b2.request_id as b2_id,
    Cast(date_part('milliseconds', b1.create_stamp) as Integer) as msi1,
    Cast(date_part('milliseconds', b2.create_stamp) as Integer) as msi2,
    (date_part('milliseconds', b1.create_stamp) - date_part('milliseconds', b2.create_stamp)) as diff
from
    request b1, request b2
where
    (b1.request_id - b2.request_id) = 1
    and (date_part('milliseconds', b1.create_stamp) - date_part('milliseconds', b2.create_stamp)) < 100
    and (date_part('milliseconds', b1.create_stamp) - date_part('milliseconds', b2.create_stamp)) > 0
order by b1.request_id;
4

3 に答える 3

2

lag()/lead()を使用して前後の値を確認したい。これは、自己結合よりもはるかに高速です。

select r.*
from (select r.*,
             lag(create_stamp) over (order by request_id) as prevcs,
             lead(create_stamp) over (order by request_id) as nextcs
      from request r
     ) r
where (date_part('milliseconds', r.create_stamp) - date_part('milliseconds', prevcs)) < 100 and
       date_part('milliseconds', r.create_stamp) - date_part('milliseconds', prevcs)) > 0
      ) or
     (date_part('milliseconds', nextcs) - date_part('milliseconds', r.create_stamp)) < 100 and
       date_part('milliseconds', nextcs) - date_part('milliseconds', r.create_stamp)) > 0
      )

lag()both andを使用する理由lead()は、ペアの両方の行を返すためです。そのような最初の行で十分な場合は、1 つの関数 (およびwhere節の半分) だけが必要です。

元のクエリが隣接するリクエスト ID を参照していることに気付きました。これはあなたが本当に欲しいものですか?または、行を で並べ替えますcreate_stampか? order byその場合は、関数ごとにパーティション内の引数を変更してください。

于 2013-06-30T17:40:51.893 に答える
1

次のクエリを検討してください。

SELECT Q.*
FROM (
    SELECT *, lag (create_stamp, 1) OVER (ORDER BY request_id) prev
    FROM request
) Q
WHERE
    create_stamp - prev <= interval '00:00:00.1';

[SQLフィドル]

100ミリ秒以内に前の1行があるようなすべての行を返します。


1順序によって決定される「前」request_id- 必要でない場合は、ORDER BY 句を適切に変更します。

于 2013-06-30T18:06:00.597 に答える
0

サブクエリを使用してクエリを単純化できるかもしれません

select b1.create_stamp as st1, b2.create_stamp as st2, b1.request_id as b1_id, 
b2.request_id as b2_id,     msi1, msi2, (msi1 - msi2) as diff 
from 
(
     select * , Cast(date_part('milliseconds', create_stamp) as Integer) as msi1
     from request 
) b1
,
(
     select * , Cast(date_part('milliseconds', create_stamp) as Integer) as msi2
     from request 
) b2 
where 
(b1.request_id - b2.request_id) = 1 and 
(msi1 - msi2) < 100 and (msi1 - msi2) > 0 
order by b1.request_id;
于 2013-06-30T17:38:30.193 に答える