3

人は、紹介された友人が行った購入に対して 10% のコミッションを受け取ります。

2 つのテーブルがあります。

  1. 参照表
  2. 取引表

参照表

Person_id    Referrer_id
3             1
4             1
5             1
6             2

取引表

   Person_id   Amount     Action     Date
   3           100        Purchase   10-20-2011
   4           200        Purchase   10-21-2011
   6           400        Purchase   12-15-2011
   3           200        Purchase   12-30-2011
   1            50        Commision  01-01-2012
   1            10        Cm_Bonus   01-01-2012
   2            20        Commision  01-01-2012

Referrer_Person_id=1 の次の結果セットを取得する方法

Month     Ref_Pur  Earn_Comm   Todate_Earn_Comm   BonusRecvd  Paid   Due
10-2011    300      30          30                  0           0     30
11-2011      0       0          30                  0           0     30
12-2011    200      20          50                  0           0     50
01-2012      0       0          50                 10          50      0


上記で使用されるラベルは次のとおりです。

Ref_Pur          = Total Referred Friend's Purchase for that month

Earn_Comm        = 10% Commision earned for that month

Todate_Earn_Comm = Total Running Commision earned upto that month

私が書いたMYSQLコード

SELECT dx1.month,
       dx1.ref_pur,
       dx1.earn_comm,
       ( @cum_earn := @cum_earn + dx1.earn_comm ) as todate_earn_comm

FROM

(
    select date_format(`date`,'%Y-%m') as month,
           sum(amount) as ref_pur , 
           (sum(amount)*0.1) as earn_comm
    from transaction tr, reference rf
    where tr.person_id=rf.person_id and
          tr.action='Purchase' and
          rf.referrer_id=1
    group by date_format(`date`,'%Y-%m')
    order by date_format(`date`,'%Y-%m')

)as dx1

JOIN (select @cum_earn:=0)e;

クエリを結合して、参照テーブルに依存しない BonusRecvd、Paid、Due trnsactions も含めるにはどうすればよいですか?

また、その月に trnx が発生していない場合でも、月 '11-2011' の行を生成します

4

1 に答える 1

1

コミッションの支払いとボーナスを結果に含めたい場合は、おそらくAction IN ('Commision', 'Cm_Bonus')、結果の計算に使用する初期データセットに対応する行 ( ) を含める必要があります。または、少なくとも、それは私が行うことであり、次のようになる可能性があります。

SELECT t.Amount, t.Action, t.Date
FROM Transaction t LEFT JOIN Reference r ON t.Person_id = r.Person_id
WHERE r.Referrer_id = 1 AND t.Action = 'Purchase'
   OR t.Person_id   = 1 AND t.Action IN ('Commision', 'Cm_Bonus')

また、毎月の SUM を計算するときは、CASE 式を使用して、さまざまな種類の に関連する金額を区別できますAction。クエリの対応する部分は次のようになります。

…
IFNULL(SUM(CASE Action WHEN 'Purchase'  THEN Amount END)      , 0) AS Ref_Pur,
IFNULL(SUM(CASE Action WHEN 'Purchase'  THEN Amount END) * 0.1, 0) AS Earn_Comm,
IFNULL(SUM(CASE Action WHEN 'Cm_Bonus'  THEN Amount END)      , 0) AS BonusRecvd,
IFNULL(SUM(CASE Action WHEN 'Commision' THEN Amount END)      , 0) AS Paid
…

値を計算するときは、Due別の変数を初期化して とまったく同じように使用できますが、次のよう@cum_earnに を減算する必要もあります。Paid

(@cum_due := @cum_due + Earn_Comm - Paid) AS Due

最後の 1 つの問題は、月が欠けているようです。それに対処するために、私は次のことを行います。

  1. 処理するサブセットから最初と最後の日付を取得します (この投稿の冒頭のクエリで取得)。

  2. 各日付に対応する月を取得します (つまり、単に同じ月の最初の別の日付)。

  3. 数値表を使用して、前のステップで計算された 2 つの月をカバーする月のリストを生成します。

  4. サブセットに存在する処理対象の月をフィルターで除外し、残りの月を使用してサブセットにダミー トランザクションを追加します。

ご覧のとおり、これらの手順を実行するときは、「処理するサブセット」に 2 回触れる必要があります。したがって、効率を高めるために、同じ (サブ) クエリを数回実行する代わりに、そのサブセットを一時テーブルに挿入してそのテーブルを使用します。

ステップ 3 で説明した数字の表は、常に手元に置いておくことをお勧めするツールです。しゃれを許せば、一度だけ初期化する必要があり、その用途は多数になる可能性があります。数字の表にデータを入力する 1 つの方法を次に示します。

CREATE TABLE numbers (n int);
INSERT INTO numbers (n) SELECT 0;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
INSERT INTO numbers (n) SELECT cnt + n FROM numbers, (SELECT COUNT(*) AS cnt FROM numbers) s;
/* repeat as necessary; every repeated line doubles the number of rows */

そして、それだけのようです。必要に応じて、上記の提案を独自の方法で使用する機会を惜しまないように、ここでは完全な解決策を投稿しません。しかし、苦労している場合、またはそれらが必要な効果に適用できることを確認したいだけの場合は、この SQL Fiddle ページを試して、「実際の」完全なソリューションを試すことができます。

于 2012-05-17T15:59:42.780 に答える