Question

I am trying to find an average of past records in the database based on a specific time frame (between 9 and 3 months ago) if there is no value recorded for a recent sale. the reason for this is recent sales on our website sometimes do not immediately collect commissions so i am needing to go back to historic records to find out what a commission rate estimate might be.

Commission rate is calculated as:

total_commission / gross_sales

It is only necessary to find out what an estimate would be if a recent sale has no "total_commission" recorded

here is what i have tried so far but i think this is wrong:

    SELECT 
     cs.*
    ,SUM(cs2.gross_sales)
    ,SUM(cs2.total_commission)
     FROM

    (SELECT 
      sale_id
    , date
    , customer_code
    , customer_country
    , gross_sales
    , total_commission
    FROM customer_sale cs ) cs 

    LEFT JOIN customer_sale cs2 
    ON cs2.customer_code = cs.customer_code
    AND cs2.customer_country = cs.customer_country
    AND cs2.date > cs.date - interval 9 month
    AND cs2.date < cs.date - interval 3 month 

    GROUP BY cs.sale_id

so that data would be structured as follows:

sale_id date         customer_code customer_country gross_sales total_commission
1       2013-12-01   cust1         united states    10000       1500
2       2013-12-01   cust2         france           20000       3000
3       2013-12-01   cust3         united states    15000       2250
4       2013-12-01   cust4         france           14000       2100
5       2013-12-01   cust5         united states    13000       1950
6       2013-12-01   cust6         france           12000       1800
7       2014-04-02   cust1         united states    10000   
8       2014-04-02   cust2         france           20000   
9       2014-04-02   cust3         united states    15000   
10      2014-04-02   cust4         france           14000   
11      2014-04-02   cust5         united states    13000   
12      2014-04-02   cust6         france           12000   

so I would need to output results from the query similar to this: (based on sales between 9 and 3 months ago from the same customer_code in the same customer_country)

sale_id date         customer_code customer_country gross_sales total_commission gross_sales_past total_commission_past
1       2013-12-01   cust1         united states    10000       1500
2       2013-12-01   cust2         france           20000       3000
3       2013-12-01   cust3         united states    15000       2250
4       2013-12-01   cust4         france           14000       2100
5       2013-12-01   cust5         united states    13000       1950
6       2013-12-01   cust6         france           12000       1800
7       2014-04-02   cust1         united states    10000                        10000            1500
8       2014-04-02   cust2         france           20000                        20000            3000
9       2014-04-02   cust3         united states    15000                        15000            2250
10      2014-04-02   cust4         france           14000                        14000            2100
11      2014-04-02   cust5         united states    13000                        13000            1950
12      2014-04-02   cust6         france           12000                        12000            1800
Was it helpful?

Solution

Your query looks mostly right, but I think your outer query needs to be GROUP BY cs.sale_id (assuming that sale_id is unique in the customer_sale table, and assuming that the date column is datatype DATE, DATETIME, or TIMESTAMP).

And I think you want to include a join predicate so that you match only match "past" rows to those rows where you don't have a total commission, e.g.

AND cs.total_commission IS NULL

And I don't think you really need an inline view.


Here's what I came up with:

SELECT cs.sale_id
     , cs.date
     , cs.customer_code
     , cs.customer_country
     , cs.gross_sales
     , cs.total_commission
     , SUM(ps.gross_sales) AS gross_sales_past
     , SUM(ps.total_commission) AS total_commission_past
  FROM customer_sale cs
  LEFT
  JOIN customer_sale ps
    ON ps.customer_code = cs.customer_code
   AND ps.customer_country = cs.customer_country
   AND ps.date > cs.date - INTERVAL 9 MONTH
   AND ps.date < cs.date - INTERVAL 3 MONTH
   AND cs.total_commission IS NULL
 GROUP
    BY cs.sale_id

Appropriate indexes will likely improve performance of the query. Likely, the EXPLAIN output will show "Using temporary; Using filesort", and that can be expensive for large sets.

MySQL will likely be able to make use of a covering index for the JOIN:

... ON customer_sale (customer_code,customer_country,date,gross_sales,total_commission).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top