web-dev-qa-db-ja.com

集計を実行して行をグループ化する

支払いまたは購入のいずれかである一連のトランザクションがあります。購入にはさまざまなタイプがあります(例:「ApplePurchase」、「OrangePurchase」)。

クーポンコードでお支払いを選択します。支払いごとに、その支払いの前に残高がゼロに達した最後の時間までのすべての購入を破棄したいと思います。次に、残りの購入を集計したいと思います。 (その言い回しとそれを肉屋にしたことをお詫びしてくれた@Andriy Mに感謝します)。

SQLでソリューション(の一部)を作成する方法についてのアドバイスをいただければ幸いです。

次にいくつかのデータ例を示します。

create table users
     (id integer primary key);

create table transactions
     (user_id integer references users (id),
     type enum('ApplePurchase', 'OrangePurchase', 'Payment'),
     coupon varchar(10),
     date_paid date,
     amount integer);

insert into users
    (id)
    values (1), (2), (3), (4), (5);

insert into transactions
    (user_id, type, coupon, date_paid, amount)
    values (1, 'ApplePurchase', NULL, '2003-01-02', 5),
           (2, 'ApplePurchase', NULL, '2003-01-02', 15),
           (1, 'Payment', 'aCoupon', '2003-01-02', 5), # here user 1's balance reaches 0
           (2, 'OrangePurchase', NULL, '2003-01-03', 10),
           (2, 'Payment', 'bCoupon', '2003-01-03', 23),
           (1, 'ApplePurchase', NULL, '2003-01-05', 15),
           (1, 'Payment', 'bCoupon', '2003-01-05', 15),
           (1, 'ApplePurchase', NULL, '2003-01-07', 15),
           (1, 'Payment', 'bCoupon', '2003-01-07', 15);

おそらく、クーポン「bCoupon」の支払いに対してこの集計を実行しようとしています。メンバー2は、そのタイプの支払いを1回、その前に3回購入します。介在する支払いがないため、購入を集計するだけで済みます(最初の行のように)。メンバー2には、そのタイプの2つの支払いがあります。最初の購入はその前に2回購入されますが、最初の購入は以前の支払いによってキャンセルされます。その場合、フォームの結果を探しています

Date       | Member |  Apple | Orange | Payment | Balance
2003-03-01 | 2      |  15    | 10     | 23      | 2
2003-05-01 | 1      |  15    | 0      | 15      | 0
2003-07-01 | 1      |  15    | 0      | 15      | 0
1
S Holt

1つのオプションは、この機能の一部をアプリケーションコードに任せることです。で関連データを照会することが可能です

select * from transactions t
    where exists(
        select 1 from transactions t2
            where t2.coupon = 'bCoupon'
                and t.user_id = t2.user_id
                and t2.date_paid > t.date_paid
    )
    order by date_paid

そして、それを折ります。

1
S Holt