クエリ設計の問題に直面していて、問題に対する私のアプローチが不必要に複雑であるかどうかわからない:
私はファクトテーブルを持っています:
Column | Type | Modifiers
------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('messages_id_seq'::regclass)
type | character varying(255) |
ts | numeric |
text | text |
score | double precision |
user_id | integer |
channel_id | integer |
time_id | integer |
created_at | timestamp without time zone |
updated_at | timestamp without time zone |
現在、それに対していくつかの分析クエリを実行しています。そのうちの 1 つ (たとえば) は次のようになります。
with intervals as (
select
(select '09/27/2014'::date) + (n || ' minutes')::interval start_time,
(select '09/27/2014'::date) + ((n+60) || ' minutes')::interval end_time
from generate_series(0, (24*60*7), 60 * 4) n
)
select
extract(epoch from i.start_time)::numeric * 1000 as ts,
extract(epoch from i.end_time)::numeric * 1000 as end_ts,
sum(avg(messages.score)) over (order by i.start_time) as score
from messages
right join intervals i
on messages.timestamp >= i.start_time and messages.timestamp < i.end_time
where messages.timestamp between '09/27/2014' and '10/04/2014'
group by i.start_time, i.end_time
order by i.start_time
おそらくわかるように、このクエリは、特定の時間バケット分布のメッセージの「スコア」属性の平均を計算し、それと並行してバケット全体の累積を計算します (ウィンドウを使用)。
次にやろうとしているのはmessages.text
、各バケットの平均に最も近い上位 5 つ (たとえば) を見つけることです。
現在、私が持っている唯一の計画は次のとおりです。
1) Join messages with the time-buckets
2) Compute a score - avg(score) over (partition by start_time) as deviation and save it against each record of the joined relation
3) Compute a rank() over (order by deviation) as rank
4) Select where rank between 1 and 5
ウィンドウ関数内でウィンドウ関数を使用することを含む設計を考え出す最初の試みであり、それが機能(rank() over (partition by start_time, order by score - avg(score) over (partition by start_time))
するかどうかを確認するつもりさえなかったので、これを命令的に段階的に書き留めた理由.
正しい方向に進んでいるかどうかについてアドバイスをいただけますか?