繁体   English   中英

选择SUM()查询的MAX()

[英]Selecting MAX() of a SUM() query

我正在尝试创建一个查询,该查询显示来自总和查询的最大值以及团队名称。 我尝试搜索,大多数答案使用LIMIT和TOP 1,这并不是我真正想要的。

因此,从此SUM查询:

SELECT Team_Name, SUM(SCORE) as Score_Total
FROM SCORE, TEAM
WHERE team.Team_ID = score.Team_ID
GROUP BY Team_Name;

返回此:

+----------------+-------------+
|   Team_Name    | Score_Total |
+----------------+-------------+
| Hackers        |         332 |
| Hammer Time    |         356 |
| Sharp Shooters |         406 |
| String Music   |         355 |
+----------------+-------------+

当我尝试通过以下代码在总和查询中使用MAX函数时:

SELECT Team_Name, MAX(Score_Total)
FROM (
SELECT Team_Name, SUM(SCORE) as Score_Total
FROM SCORE, TEAM
WHERE team.Team_ID = score.Team_ID
GROUP BY Team_Name) s;

我得到这个:

+-----------+------------------+
| Team_Name | MAX(Score_Total) |
+-----------+------------------+
| Hackers   |              406 |
+-----------+------------------+

如您所见,最大值确实正确,但是与最大值相对应的团队名称却不正确。 我的代码有问题吗?

考虑以下查询:

SELECT Team_Name, MAX(Score_Total), MIN(Score_Total)
FROM (
SELECT Team_Name, SUM(SCORE) as Score_Total
FROM SCORE, TEAM
WHERE team.Team_ID = score.Team_ID
GROUP BY Team_Name) s;

它应该返回哪个队名? 总分最高的团队还是总分最低的团队? 如果聚合是AVG()并且行中都不包含该值怎么办?

团队名称不是来自找到最大值(或最小值)的行。 实际上,MySQL允许模棱两可的查询。 它返回列中众多团队名称之一,但是返回哪个团队是任意的。

注意,“任意”并不意味着“随机”。 实际上,MySQL返回在组中找到的第一个值。 但这不是保证行为的一部分,而只是实现的巧合。 如果他们在将来的版本中更改了实现,并且开始返回该组中其他选择的任意行,则不允许您抱怨。 ;-)

这种查询实际上在大多数SQL品牌和SQL标准中都是错误的。 您可以使用SET SQL_MODE=ONLY_FULL_GROUP_BY使SQL更严格地遵循SQL标准。

解决问题的最简单方法是:

SELECT Team_Name, SUM(SCORE) as Score_Total
FROM SCORE, TEAM
WHERE team.Team_ID = score.Team_ID
GROUP BY Team_Name
ORDER BY Score_Total DESC
LIMIT 1;

当您在查询中未指定分组条件时,MySQL将返回任何随机值。

如果您想从子查询中获得最大价值,建议您对数据集进行排序,然后仅获取第一行:

select team_name, score_total
from
    (
        select team_name, sum(score) as score_total
        from score, team
        where team.team_id = score.team_id
        group by team_name
    ) as a
order by
    score_total desc
limit 1;

一些建议:

进行笛卡尔连接并在where子句上进行过滤的insetad使用连接。 另外,按ID字段分组:

select team_name, score_total
from
    (
        select team_name, sum(score) as score_total
        from 
            score as s 
            inner join team as t on s.team_id = t.team_id
        group by 
            t.team_id
    ) as a
order by
    score_total desc
limit 1;

一种更简单的方法:

select team_name, sum(score) as score_total
from score as s inner join team as t on s.team_id = s.team_id
group by team_id
order by sum(score) desc
limit 1

好的,所以根据您的表结构,您可以执行此操作

SELECT t1.Team_Name, SUM(s1.score) as score FROM SCORE s1
INNER JOIN TEAM t1 USING (Team_ID)
GROUP BY s1.Team_ID
UNION
SELECT t2.Team_Name, MAX(s2.score) as maxscore FROM SCORE s2
INNER JOIN TEAM t2 USING (Team_ID)
GROUP BY s2.Team_ID
UNION
SELECT t3.Team_Name, MIN(s3.score) as minscore FROM SCORE s3
INNER JOIN TEAM t3 USING (Team_ID)
GROUP BY s3.Team_ID

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM