使用组和最新条目计算平均分数

时间:2013-03-22 10:14:34

标签: mysql

我希望能够使用MySql为每个联系人获得最新3个CampaignId的平均分数。

   [id], [ContactId], [CampaignId], [Score]
     1    1             100             5
     2    1             100             7
     3    1             101             1
     4    1             102             3
     5    1             103             2
     6    1             103             2
     7    2             100             1
     8    2             103             2
     9    3             103             1
     10   3             104             3
     11   3             105             2
     12   3             106             4
     13   4             101             5

结果将是: -

[ContactId], [AvgScore]   (worked out by)
      1          2.66     (1 + 3 + 2 + 2 ) /3 
      2          1.50     (1 + 2) / 2  (as there are only two campaigns)
      3          3.00     (3 + 2 + 4) / 3 
      4          5.00     (5) / 1  (as there is only one campaign)

编辑我已设法获得单个联系人的结果,但也想尝试为所有联系人解决问题。

select ContactId, sum(Score), sum(Count)
from  (
  select 
    ContactId, CampaignId, sum(Score) Score, count(distinct CampaignId) Count
    from stats
  where
     ContactId = 1
  group by
      CampaignId, ContactId
order by CampaignId DESC limit 3) a;

2 个答案:

答案 0 :(得分:3)

   DROP TABLE IF EXISTS stats;

   CREATE TABLE stats
   (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
   ,ContactId INT NOT NULL
   ,CampaignId INT NOT NULL
   ,Score INT NOT NULL
   );

   INSERT INTO stats VALUES
   (1,1,100,5),
   (2,1,100,7),
   (3,1,101,1),
   (4,1,102,3),
   (5,1,103,2),
   (6,1,103,2),
   (7,2,100,1),
   (8,2,103,2),
   (9,3,103,1),
   (10,3,104,3),
   (11,3,105,2),
   (12,3,106,4),
   (13,4,101,5);

   SELECT x.* 
     FROM stats x 
     JOIN stats y 
       ON y.contactid = x.contactid 
      AND y.campaignid >= x.campaignid 
    GROUP 
       BY x.id 
   HAVING COUNT(DISTINCT y.campaignid) <=3;
   +----+-----------+------------+-------+
   | id | ContactId | CampaignId | Score |
   +----+-----------+------------+-------+
   |  3 |         1 |        101 |     1 |
   |  4 |         1 |        102 |     3 |
   |  5 |         1 |        103 |     2 |
   |  6 |         1 |        103 |     2 |
   |  7 |         2 |        100 |     1 |
   |  8 |         2 |        103 |     2 |
   | 10 |         3 |        104 |     3 |
   | 11 |         3 |        105 |     2 |
   | 12 |         3 |        106 |     4 |
   | 13 |         4 |        101 |     5 |
   +----+-----------+------------+-------+

   SELECT contactid
        , SUM(score)/COUNT(DISTINCT campaignid) avgscore 
     FROM 
        ( SELECT x.* 
            FROM stats x 
            JOIN stats y 
              ON y.contactid = x.contactid 
             AND y.campaignid >= x.campaignid 
           GROUP 
              BY x.id 
          HAVING COUNT(DISTINCT y.campaignid) <=3
        ) a 
    GROUP 
       BY contactid;
   +-----------+----------+
   | contactid | avgscore |
   +-----------+----------+
   |         1 |   2.6667 |
   |         2 |   1.5000 |
   |         3 |   3.0000 |
   |         4 |   5.0000 |
   +-----------+----------+

答案 1 :(得分:0)

你能在下面试试吗?

select contactId ,sum(Score)/count(distinct CampaignId) from (
SELECT  
    @rank:= case when @a= t1.ContactId then case when @cmpId=CampaignId then @rank else @rank+1 end else 0 end as rank,
    @a:=  t1.ContactId as contactId ,
    @cmpId:=CampaignId CampaignId,
    Score

FROM stats t1 order by ContactId,CampaignId desc
) as rankorder,(Select @a:=0,@cmpId:=0,@rank=0) as temp
where rank<=2 
group by contactId 
order by contactId