1

このプロジェクトでは Postgress データベースを使用していますが、この質問はどのデータベースにも適用できます。

データベースからのレコードの選択をより効率的にする必要があります。システムに登録されている各アクティビティのレコードを含むテーブル Activity があります。

表アクティビティは、次の列で構成されています

id             integer 
time_stamp     time stamp without timezone
computer_id    varchar(255)
user_id        varchar(255)
...

一般に、単純な結果が必要です。5 分またはその他の期間のタイム スライスを指定できる必要があります。また、各タイム スライスにレコードがあるかどうかを確認する必要があります。したがって、最終的には、タイム スライスごとに True または False の結果が必要です。

True の場合はテーブルに色を付けるか、False の場合は空白のままにする必要があります。

do while ループを実行し、タイム スライスごとに多数のレコードを選択するプログラム ソリューションを作成しました。

例えば:

select *
from Activity
where time_stamp between prev_Time and curr_Time 

これは機能しますが、非常に遅いです。タイム スライスが 5 分の場合、24 時間 x 60 分 / 5 分 = 288 の選択クエリがあります。

1 つの高速選択クエリを作成する方法を見つける必要があります。ストアド プロシージャを作成できません。さらに、開始時刻から終了時刻までのすべての期間を 5 分のグループで表示するために SQL を記述する方法がわからないこともよくあります。

コード内であっても、どのソリューションも受け入れられますが、高速である必要があります。応答は最大 10 秒以内にする必要があります。

4

1 に答える 1

1

次のような間隔を作成するには、 generate_series()関数を使用できます。

select g, count(a.id)
from generate_series(
    '20131017 07:00'::timestamp,
    '20131017 08:00'::timestamp,
    '5 minutes'::interval
) as g
   left outer join Activity as a on
      a.time_stamp >= g and a.time_stamp < g + '5 minutes'::interval
group by g
order by g

count = 0 のレコードが必要ない場合は、次のクエリを使用できます。

with cte as (
    select
        (extract(epoch from time_stamp - '20131017 07:00'::timestamp) / 60)::int / 5 as p
    from Activity
    where time_stamp <= '20131017 08:00'::timestamp  
)
select
    '20131017 07:00'::timestamp + ((p * 5)::text || ' minutes')::interval, count(*)
from cte
group by p

sql fiddle demo

于 2013-10-17T17:11:14.313 に答える