2013-10-03 74 views
1

所以我试图建立一个查询,它会告诉我哪些用户对每种活动都有最多的点数。你可以看到下面的表结构。每个活动都有一个activity_typeid,每个活动都携带一定的activity_weight在同一个查询中使用SUM和DISTINCT

在下面的例子中,鲍勃得到了50分的通话和100分的会议。詹姆斯得到了100分的通话和100分的会议。

userid  activity_typeid  activity_weight 
------------------------------------------------------------ 
123 (Bob) 8765 (calls)    50 
123 (Bob) 8121 (meetings)    100 
431 (James) 8765 (calls)    50 
431 (James) 8121 (meetings)   100 
431 (James) 8765 (calls)    50 

我希望能够输出如下:

  1. 最佳表现进行通话=詹姆斯
  2. 的会议=鲍勃·詹姆斯
  3. 最佳表现。

我不知道activity_typeid的提前,因为它们是随机进入,所以我想知道是否有可能建立某种形式的查询计算总和为每个不同的/唯一activity_typeid

非常感谢。

+0

(詹姆斯)(电话)为什么重复在你的表中? – user4035

+0

对不起,我应该更好地解释一下。每次执行此操作(调用)时,都会在此表中输入一个新条目。所以,他的总积分又增加了50分。所以这不是每个人都说的重复。 – user2656127

+0

现在就来看看,你说詹姆斯有100分的电话= 50 + 50 – user4035

回答

2

你需要的是相当于分析功能DENSE_RANK()。一种方法做这件事,如果你需要优秀员工的每一项活动

SELECT a.activity_typeid, GROUP_CONCAT(a.userid) userid 
    FROM 
(
    SELECT activity_typeid, userid, SUM(activity_weight) activity_weight 
    FROM table1 
    -- WHERE ... 
    GROUP BY userid, activity_typeid 
) a JOIN 
(
    SELECT activity_typeid, MAX(activity_weight) activity_weight 
    FROM 
    (
    SELECT activity_typeid, userid, SUM(activity_weight) activity_weight 
     FROM table1 
     -- WHERE ... 
    GROUP BY userid, activity_typeid 
) q 
    GROUP BY activity_typeid 
) b 
    ON a.activity_typeid = b.activity_typeid 
    AND a.activity_weight = b.activity_weight 
GROUP BY activity_typeid 

另一种方式来模拟DENSE_RANK()在MySQL中是利用会话变量

SELECT activity_typeid, GROUP_CONCAT(userid) userid 
    FROM 
(
    SELECT activity_typeid, userid, activity_weight, 
     @n := IF(@g = activity_typeid, IF(@v = activity_weight, @n, @n + 1) , 1) rank, 
     @g := activity_typeid, @v := activity_weight 
    FROM 
    (
    SELECT activity_typeid, userid, 
      SUM(activity_weight) activity_weight 
     FROM table1 
    -- WHERE ... 
    GROUP BY activity_typeid, userid 
) q CROSS JOIN (SELECT @n := 0, @g := NULL, @v := NULL) i 
    ORDER BY activity_typeid, activity_weight DESC, userid 
) q 
WHERE rank = 1 
GROUP BY activity_typeid 

输出:

 
| ACTIVITY_TYPEID | USERID | 
|-----------------|---------| 
|   8121 | 123,431 | 
|   8765 |  431 | 

这里是​​演示两个查询

+0

谢谢!很好的工作:D – user2656127

+0

如果我想添加一个WHERE子句,我应该在a,b和c中添加它还是只添加一次? – user2656127

+0

@ user2656127非常欢迎:)查看更新后的答案。你希望两个'WHERE'子句是相同的。 – peterm

0

您必须使用GROUP BY语句来计算每个用户和每个活动typeid的总和。尝试是这样的:

SELECT userid, activity_typeid, SUM(activity_weight) 
FROM table 
GROUP BY userid, activity_typeid 

然后用这个作为一个子查询,以确定每个activity_typeid表现最佳。

+0

是的,子查询是我需要一点帮助。有小费吗?谢谢! – user2656127

+0

看看这个:http://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-results – Dan

+0

啊这看起来像我需要做的,谢谢你真是太棒了! – user2656127

0

如果要使用聚合函数,则需要使用GROUP BY而不是DISTINCT。您将按useridactivity_typeid进行分组,并选择SUM(activity_weight)

0

当然,仅仅使用GROUP BY这样的:

SELECT t.userid, t.activity_typeid, sum(t.activity_weight) 
FROM YOURTABLE t 
GROUP BY t.userid, t.activity_typeid 
0

查询选择(单)表现最好的一个给定的活动:

SELECT userid, activity_typeid, SUM(activity_weight) 
FROM ? 
WHERE activity_typeid = ? 
GROUP BY userid 
ORDER BY SUM(activity_weight) DESC 
LIMIT 1 

您可以将LIMIT改变输出顶部5或10个表演者,然后用代码检查他们,看看你想表现出什么(例如,如果两个人得分相同)。

+0

谢谢!问题是 WHERE activity_typeid =? 这就是我不知道如何解决,因为我不知道这一点,并且想要遍历该表中的所有id(其中id与之匹配) – user2656127

+0

您知道可以在运行时构建查询当你知道'activity_typeid'?查找“参数化查询”以查看如何轻松完成。 –

+0

听起来像我需要的,谢谢! – user2656127