在同一查询中使用 SUM 和 DISTINCT
Posted
技术标签:
【中文标题】在同一查询中使用 SUM 和 DISTINCT【英文标题】:using SUM and DISTINCT in the same query 【发布时间】:2013-10-03 07:51:26 【问题描述】:因此,我正在尝试构建一个查询,该查询将向我显示对于每种类型的活动,哪些用户的得分最高。您可以在下面看到表格结构。每个活动都有一个activity_typeid,每个活动都有一个特定的activity_weight。
在下面的示例中,Bob 的通话得分为 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
我希望能够输出以下内容:
-
通话表现最佳 = 詹姆斯
会议表现最佳者 = Bob, James。
我事先不知道 activity_typeid,因为它们是随机输入的,所以我想知道是否可以构建某种查询来计算每个 DISTINCT/UNIQUE activity_typeid 的总和?
提前非常感谢。
【问题讨论】:
为什么(James)(呼叫)在您的表中重复? 对不起,我应该解释得更好。每次执行此操作(调用)时,都会在此表中输入一个新条目。因此,他的总分又增加了 50 分。所以说这不是重复的。 现在看,你说,詹姆斯有 100 分的电话 = 50 + 50 您能否提供此表的 SQL 代码和 SQLFiddle 上的示例数据,以便人们检查他们的答案。加上所需的输出。 【参考方案1】:你需要的是解析函数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
在 mysql 中模拟 DENSE_RANK()
的另一种方法是利用会话变量
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 |用户名 | |-----------------|---------| | 8121 | 123,431 | | 8765 |第431章这是 SQLFiddle 两个查询的演示
【讨论】:
如果我想添加 WHERE 子句,我应该在 a、b 和 c 中添加它还是只在末尾添加一次? @user2656127 不客气 :) 查看更新的答案。您希望两个WHERE
子句相同。
非常感谢您的精彩回答。如果我可以再用一件事打扰你。我希望在这里运行 1 个额外的连接,主要是为了使用用户 ID 从用户表中获取用户名。我应该把它放在最后吗?此外,此代码是否适用于表中无限数量的 activity_typeid(即驱动 10 种不同类型活动的竞赛),还是仅适用于一组数字?再次感谢:D
@user2656127 您只需要用户名还是还需要用户 ID?
好吧,我将使用 userid 加入 users 表来选择 name 和 profilepicture。【参考方案2】:
您必须使用GROUP BY
语句来计算每个用户和每个活动类型ID 的总和。试试这样的:
SELECT userid, activity_typeid, SUM(activity_weight)
FROM table
GROUP BY userid, activity_typeid
然后将其用作子查询来确定每个 activity_typeid 的最佳执行者。
【讨论】:
是的,子查询是我需要一点帮助的地方。有小费吗?谢谢! 看看这个:***.com/questions/12113699/…【参考方案3】:如果你想使用聚合函数,你需要使用GROUP BY
,而不是DISTINCT
。您可以按userid
和activity_typeid
分组,然后选择SUM(activity_weight)
。
【讨论】:
【参考方案4】:当然,只要像这样使用 group by :
SELECT t.userid, t.activity_typeid, sum(t.activity_weight)
FROM YOURTABLE t
GROUP BY t.userid, t.activity_typeid
【讨论】:
【参考方案5】:查询以选择给定活动的(单个)表现最佳者:
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 名表演者,然后在代码中检查它们以查看您要显示的内容(例如,如果两个人的分数相同)。
【讨论】:
谢谢!问题是 WHERE activity_typeid = ?这就是我不确定如何解决的问题,因为我不知道,并且想遍历该表中的所有 id(其中一个 id 匹配) 当您知道activity_typeid
时,您知道可以在运行时构建查询吗?查找“参数化查询”以了解如何轻松完成。以上是关于在同一查询中使用 SUM 和 DISTINCT的主要内容,如果未能解决你的问题,请参考以下文章
在同一个 SQL 查询中运行正常的 pull 和 sum()
在同一个 SELECT sql 查询中从 SUM() 计算百分比