选择MAX值并限制行

时间:2017-05-03 13:36:05

标签: mysql sum

我有3张桌子:

比赛日:

matchday_id | season_id | userid | points | matchday
----------------------------------------------------
1           |  1        | 1      | 33     | 1
2           |  1        | 2      | 45     | 1
etc

玩家

userid | username
-----------------
1      | user1
2      | user2
etc.

季节

seasons_id  | title  | userid
----------------------------
1           | 2011   | 3
2           | 2012   | 10
3           | 2013   | 5

我的查询:

SELECT s.title, p.username, SUM(points) FROM matchdays m
INNER JOIN players p ON p.userid = m.userid
INNER JOIN seasons s ON m.userid = s.userid
group by s.season_id

这导致(例子!):

title | username | SUM(points)
------------------------------
2011  | user3    | 3744
2012  | user10   | 3457
2013  | user5    | 3888

它的外观应该是每个赛季的胜利者(最高分)。现在,标题和用户名是正确的,但点的总和太高了。我无法弄清楚计算出的金额。理想情况下,总和是为每个用户添加一个季节的每个比赛日。

2 个答案:

答案 0 :(得分:0)

你加入是错误的,尝试类似:

SELECT  s.title, p.username, SUM(m.points) as points FROM matchdays m
JOIN players p ON p.userid = m.userid
JOIN seasons s ON m.season_id = s.season_id
group by s.season_id, p.userid
ORDER by points DESC;

正如所指出的那样,用户在“赛季”中并不需要/不需要#id;表

答案 1 :(得分:0)

你的主要问题是你只按季节分组。因此,无论玩家如何,你的SUM都会在一个赛季的所有积分上运行。

无论如何,整个方法都是错误的。 "缺陷"在季节表中使用userid是你最大的问题,你似乎知道它。 我将向您解释如何在数据库中一次性计算您的排名,并始终随意使用它们,这将为您节省很多麻烦,显然也可以节省一些CPU和加载时间。

首先创建一个新表"排名":

CREATE table rankings (season_id INT, userid INT, points INT, rank INT)

如果您有很多玩家,请为points

之前的所有列编制索引

然后,填写每个季节的表格:

这是每个赛季结束时运行的单击操作。 因此,目前,每个赛季都需要多次运行。

这里的关键是计算每个球员本赛季的排名,这是必须拥有的,以后会非常方便。因为MySQL没有窗口功能,所以我们必须使用一个老技巧:递增计数器。

我分解了。

这将计算一个赛季的积分,并提供该赛季的排名:

SELECT season_id, userid, SUM(points) as points 
FROM matchdays
WHERE season_id = 1
GROUP BY season_id, userid
ORDER BY points DESC

现在我们调整此查询以添加排名列:

SELECT
   season_id, userid, points,
   @curRank := @curRank + 1 AS rank
FROM
(   
    SELECT season_id, userid, SUM(points) as points 
    FROM matchdays
    WHERE season_id = 1
    GROUP BY season_id, userid
)   T, 
(
    SELECT @curRank := 0
) R
ORDER BY T.points DESC

那就是它。 现在我们可以将这个计算的结果插入到我们的排名表中,以便将它存储一次:

INSERT INTO rankings
SELECT
   season_id, userid, points,
   @curRank := @curRank + 1 AS rank
FROM
(   
    SELECT season_id, userid, SUM(points) as points 
    FROM matchdays
    WHERE season_id = 1
    GROUP BY season_id, userid
)   T, 
(
    SELECT @curRank := 0
) R
ORDER BY T.points DESC

更改season_id = 1并重复每个季节。 将此查询保存在某个地方,并在将来每个季节结束时运行一次。

现在您有一个正确的数据库计算排名和一个很好的排名表,您可以随时查询。

你想要每个赛季的冠军?就这么简单:

SELECT S.title, P.username, R.points
FROM Ranking R
INNER JOIN seasons S ON R.season_id=S.season_id
INNER JOIN players P ON R.userid=P.userid
WHERE R.rank = 1

您会发现,随着时间的推移,您可以使用排名表非常简单地完成很多不同的事情。