在我们的项目中,我们有一个用户表,其中包含姓名和不同类型的分数(总分,任务分数等)的用户数据。如何计算这些值无关紧要,但要将它们分开。
让我们看一下表'用户',如下所示
id name score_overall score_trade score_quest
1 one 40000 10000 20000
2 two 20000 15000 0
3 three 30000 1000 50000
4 four 80000 60000 3000
为了显示分数,则存在用于每种分数的虚拟表和一个表,其中用户名与点分数和等级一起存储。所有表看起来都一样,但名称不同。
id name score rank
它们是分开的,允许用户搜索和过滤表格。让我们说玩家“playerX”有一行排名为60.所以如果我过滤“playerX”的分数,我只会看到这一行,但排名为60.这意味着排名是“难以存储的”而不仅仅是通过rownumber或类似的东西动态显示。
不同的得分表通过cronjob填充(并使用附加虚拟表),其中包含以下内容:
order by score
这意味着:Wheren有五个特定分数,还有五个分数表和虚拟表,共计6个。
如何优化?
我想做的是优化整个事情并删除重复的表(如果可能的话,避免使用虚拟表)将所有得分数据存储在一个包含以下列的表中:
userid, overall_score, overall_rank, trade_score, trade_rank, quest_score, quest_rank
现在我的问题是如何以最好的方式做到这一点,是否有另一种方式如上所示(包含所有不同的表格)?欢迎使用MYSQL语句和/或php代码。 前段时间我尝试使用行号,但这不起作用a)因为它们不能用于插入语句和b)因为当过滤每个玩家时(如上例中的'playerX')将在等级1上这是唯一一条返回的行。
答案 0 :(得分:0)
好吧,您可以尝试使用以下配置创建表:
id | name | score_overall | score_trade | score_quest | overall_rank | trade_rank | quest_rank
如果这样做,您可以使用以下查询来填充表格:
SET @overall_rank:=-(SELECT COUNT(id) FROM users);
SET @trade_rank:=@overall_rank;
SET @quest_rank:=@overall_rank;
SELECT *
FROM users u
INNER JOIN (SELECT id,
@overall_rank:=@overall_rank+1 AS overall_rank
FROM users
ORDER BY score_overall DESC) ovr
ON u.id = ovr.id
INNER JOIN (SELECT id,
@trade_rank:=@trade_rank+1 AS trade_rank
FROM users
ORDER BY score_trade DESC) tr
ON u.id = tr.id
INNER JOIN (SELECT id,
@quest_rank:=@quest_rank+1 AS quest_rank
FROM users
ORDER BY score_quest DESC) qr
ON u.id = qr.id
ORDER BY u.id ASC
我为你准备了SQL-fiddle。
虽然我认为如果你开始获得很多记录,表现会有所影响。
一点解释:@*_rank
事物是SQL变量。每增加一行,它们就会增加1。