私は取引テーブルを扱っています。過去 5 分間と 30 分間、1 時間、2 時間、3 時間、4 時間、1 日間、5 日間、10 日間に同じ顧客によって実行されたトランザクションの数を決定するために、いくつかの変数を生成したいと考えています。トランザクション テーブルにそのような列を生成する効率的な方法は何ですか? -- 解決策は、各トランザクション時間までの累計です。Oracle やその他の SQL バリアントを自由に使用できます。
2 に答える
これらの統計は時間的な性質のために絶えず変化するため、これらの統計を物理的に保存することは望まないと思います。解決策は、これらの統計をどのように使用するかによって異なります。私は2つの主な方法を考えることができます:
特定の一意の顧客に対するアドホッククエリ-この場合、顧客IDと時間枠をパラメーターとして受け取り、顧客ごとに関連するトランザクション数を返すストアドプロシージャがあります。
複数のウィンドウにわたる複数の顧客の「標準化された」レポート-この場合、適切な期間のすべての顧客と顧客ごとのトランザクション数を選択する期間ごとのビューが必要になる可能性があります。
おそらく、ユースケースに関する詳細情報を提供していただければ、より具体的にすることができます。
単一の顧客の場合:
私が思いつくことができる最善の解決策は、分析を使用することではなく、サブファクター化されたクエリ/一般的なテーブル式を使用することです。Oracleは一般に、それらを一時テーブルに変換するかどうかを知るのに十分賢く、複数が同じデータを渡した後のコストを削減します。
with txns as
(select customer_id
txn_id,
txn_ts
from transaction_table
where customer_id = ?
AND txn_ts >= SYSTIMESTAMP - NUMTODSINTERVAL(10, 'DAY')
)
select customer_id,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(5/1440, 'day'))
as txn_5_min,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(30/1440, 'day'))
as txn_30_min,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(1/24, 'day'))
as txn_1_hour,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(2/24, 'day'))
as txn_2_hour,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(3/24, 'day'))
as txn_3_hour,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(4/24, 'day'))
as txn_4_hour,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(1, 'day'))
as txn_1_day,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(2, 'day'))
as txn_2_day,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(5, 'day'))
as txn_5_day,
(select count(*) from txns
where event_ts >= systimestamp - numtodsinterval(10, 'day'))
as txn_10_day
from customer
WHERE customer_id = ?;
マルチカスタマーの場合にも同様の実装を使用できますが、効率は確実に低下します。5分間のレベルのデータが、取得が完了するまでにすべての顧客にとって古くなるかどうかを検討してください。