mySQL 按 table 中值的总和排序
mySQL rank order by sum of values in table
我有一个 mySQL 数据库 table 我用来存储发送给人们的消息。每条消息都可以包含点。我想知道是否有一个查询可以汇总每个人的所有积分并按排名排序?
目前我知道如何获得我正在寻找的输出的唯一方法是 运行 这个:
SELECT SUM(messagePoints) AS totalPoints FROM Messages
然后将结果存储在PHP中,并按totalPoints对结果进行排序。我确定有一种方法可以完全通过查询来完成此操作,但我不知道从哪里开始。希望有人能给我一些建议。
Messages
Table 例子
messageID | personID | dateOfMessage | messagePoints
----------------------------------------------------------------
1 | 10 | 2017-01-05 00:00:00 | 5
2 | 10 | 2017-01-16 00:00:00 | 3
3 | 20 | 2017-01-16 00:00:00 | 4
4 | 10 | 2017-02-01 00:00:00 | 6
5 | 20 | 2017-02-07 00:00:00 | 7
理想结果:
personID | totalPoints | rank
--------------------------------
10 | 14 | 1
20 | 11 | 2
如果上述输出是可能的,我想知道是否可以使用日期范围过滤器生成相同的输出,例如仅来自二月份的消息。
仅二月消息的理想结果:
personID | totalPoints | rank
--------------------------------
20 | 7 | 1
10 | 6 | 2
编辑:
如果更简单,我最终需要在我的应用程序中显示 1 个人的总积分和排名(由 PHP 提供),即 personID = 10
的结果我需要总积分和排名整体并按日期过滤。所以可能有 4 个单独的查询。
personID=10 的理想总体结果:
totalPoints
-----------
14
和
rank
----
1
personID=10 的理想结果按二月过滤:
totalPoints
-----------
6
和
rank
----
2
如果您不需要结果中的排名 - 这是一个基本的聚合查询:
select m.personID, sum(messagePoints) as totalPoints
from messages m
group by m.personID
order by totalPoints desc
在结果中包含行号(排名)的一种方法是使用临时 table 和 AUTO_INCREMENT 列作为排名:
drop temporary table if exists tmp_messages;
create temporary table tmp_messages(
rank int auto_increment primary key,
personID int,
totalPoints int
) as
select null as rank, m.personID, sum(messagePoints) as totalPoints
from messages m
group by m.personID
order by totalPoints desc;
select * from tmp_messages order by rank;
您当然可以在 WHERE 子句中包含过滤器,例如:
select m.personID, sum(messagePoints) as totalPoints
from messages m
where m.dateOfMessage >= '2017-02-01'
and m.dateOfMessage < '2017-03-01'
group by m.personID
并且您可以 select 特定用户:
select * from tmp_messages where personID = 10
您可以试试下面的代码来获取排名,您可以使用 where 子句来过滤日期。
select personID, SUM(messagePoints) AS totalPoints,@curRank := @curRank + 1 AS rank
from Messages, (select @curRank :=0) r
group by personID
order by totalPoints
我有一个 mySQL 数据库 table 我用来存储发送给人们的消息。每条消息都可以包含点。我想知道是否有一个查询可以汇总每个人的所有积分并按排名排序?
目前我知道如何获得我正在寻找的输出的唯一方法是 运行 这个:
SELECT SUM(messagePoints) AS totalPoints FROM Messages
然后将结果存储在PHP中,并按totalPoints对结果进行排序。我确定有一种方法可以完全通过查询来完成此操作,但我不知道从哪里开始。希望有人能给我一些建议。
Messages
Table 例子
messageID | personID | dateOfMessage | messagePoints
----------------------------------------------------------------
1 | 10 | 2017-01-05 00:00:00 | 5
2 | 10 | 2017-01-16 00:00:00 | 3
3 | 20 | 2017-01-16 00:00:00 | 4
4 | 10 | 2017-02-01 00:00:00 | 6
5 | 20 | 2017-02-07 00:00:00 | 7
理想结果:
personID | totalPoints | rank
--------------------------------
10 | 14 | 1
20 | 11 | 2
如果上述输出是可能的,我想知道是否可以使用日期范围过滤器生成相同的输出,例如仅来自二月份的消息。
仅二月消息的理想结果:
personID | totalPoints | rank
--------------------------------
20 | 7 | 1
10 | 6 | 2
编辑:
如果更简单,我最终需要在我的应用程序中显示 1 个人的总积分和排名(由 PHP 提供),即 personID = 10
的结果我需要总积分和排名整体并按日期过滤。所以可能有 4 个单独的查询。
personID=10 的理想总体结果:
totalPoints
-----------
14
和
rank
----
1
personID=10 的理想结果按二月过滤:
totalPoints
-----------
6
和
rank
----
2
如果您不需要结果中的排名 - 这是一个基本的聚合查询:
select m.personID, sum(messagePoints) as totalPoints
from messages m
group by m.personID
order by totalPoints desc
在结果中包含行号(排名)的一种方法是使用临时 table 和 AUTO_INCREMENT 列作为排名:
drop temporary table if exists tmp_messages;
create temporary table tmp_messages(
rank int auto_increment primary key,
personID int,
totalPoints int
) as
select null as rank, m.personID, sum(messagePoints) as totalPoints
from messages m
group by m.personID
order by totalPoints desc;
select * from tmp_messages order by rank;
您当然可以在 WHERE 子句中包含过滤器,例如:
select m.personID, sum(messagePoints) as totalPoints
from messages m
where m.dateOfMessage >= '2017-02-01'
and m.dateOfMessage < '2017-03-01'
group by m.personID
并且您可以 select 特定用户:
select * from tmp_messages where personID = 10
您可以试试下面的代码来获取排名,您可以使用 where 子句来过滤日期。
select personID, SUM(messagePoints) AS totalPoints,@curRank := @curRank + 1 AS rank
from Messages, (select @curRank :=0) r
group by personID
order by totalPoints