MySQL自我加入以获得过去的平均值

时间:2014-04-08 22:01:44

标签: mysql sql datetime self-join

如果最近的销售没有记录值,我试图根据特定的时间范围(9到3个月前)找到数据库中过去记录的平均值。这样做的原因是我们网站上的近期销售有时不会立即收取佣金,所以我需要回到历史记录,找出佣金率可能是多少。

佣金率计算如下:

total_commission / gross_sales

如果最近的销售没有记录“total_commission”,只需要了解估算值是什么

这是我到目前为止所尝试过的,但我认为这是错误的:

    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

这样数据的结构如下:

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   

所以我需要输出类似于此的查询结果:(基于同一customer_country中相同customer_code的9到3个月之前的销售额)

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

1 个答案:

答案 0 :(得分:0)

您的查询看起来大部分是正确的,但我认为您的外部查询需要为GROUP BY cs.sale_id(假设sale_id在customer_sale表中是唯一的,并假设date列是数据类型DATE,DATETIME,或TIMESTAMP)。

我认为你想要包含一个连接谓词,这样你只匹配匹配&#34;过去&#34;行到那些你没有总佣金的行,例如

AND cs.total_commission IS NULL

我认为你真的不需要内联视图。


这是我想出的:

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

适当的索引可能会提高查询的性能。可能,EXPLAIN输出将显示&#34;使用临时;使用filesort&#34;,这对于大型集合来说可能很昂贵。

MySQL可能会使用JOIN的覆盖索引:

... ON customer_sale (customer_code,customer_country,date,gross_sales,total_commission).