18か月にわたる1,000のエンティティにまたがるトランザクションのデータベースで、クエリを実行して、可能な30日間ごとにentity_id
トランザクション量のSUMとその30日間のトランザクションのCOUNTでグループ化します。クエリを実行できる方法でデータを返します。多くのテストの後、このコードは私が望むものの多くを達成します:
SELECT id, trans_ref_no, amount, trans_date, entity_id,
SUM(amount) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_total,
COUNT(id) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_count
FROM transactiondb;
そして、次のような構造の大きなクエリで使用します。
SELECT * FROM (
SELECT id, trans_ref_no, amount, trans_date, entity_id,
SUM(amount) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_total,
COUNT(id) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_count
FROM transactiondb ) q
WHERE trans_count >= 4
AND trans_total >= 50000;
このクエリがカバーしないケースは、トランザクションカウントが複数の月にまたがる場合でも、互いに30日以内である場合です。このタイプのクエリはPostgresで可能ですか?もしそうなら、私はすべての入力を歓迎します。他のトピックの多くでは、ローリングではなく「実行」アグリゲートについて説明しています。
更新
CREATE TABLE
スクリプト:
CREATE TABLE transactiondb (
id integer NOT NULL,
trans_ref_no character varying(255),
amount numeric(18,2),
trans_date date,
entity_id integer
);
サンプルデータはこちらにあります。PostgreSQL 9.1.16を実行しています。
理想的な出力が含まれるであろうSUM(amount)
とCOUNT()
、ローリング30日間にわたるすべてのトランザクションの。たとえば、次の画像を参照してください。
緑の日付の強調表示は、クエリに含まれるものを示します。黄色の行の強調表示は、セットの一部になりたいレコードを示します。
前の読書:
entity_id
30日間に同じ行を蓄積します。同じトランザクションに複数のトランザクションが存在するか、その組み合わせが一意に定義されていますか?テーブル定義に制約がないかPKがありますが、制約が欠落しているようです...(trans_date, entity_id)
UNIQUE
id
主キーです。1日にエンティティごとに複数のトランザクションが存在する場合があります。
every possible 30-day period by entity_id
期間はいつでも開始できるということですが、(うるう年ではない)1年で365の期間が可能ですか?または、実際の取引のある日のみを個別に期間の開始と見なしますentity_id
か?どちらにしても、テーブル定義、Postgresバージョン、サンプルデータ、およびサンプルの期待される結果を提供してください。