在为游戏生成排名时,我编写了一个类似于以下代码的查询(为了简洁起见,省略了很多列),并注意到排名产生了看似胡言乱语(第一个查询)。 但是,更改引用游戏编号的表会产生正确的结果(第二个查询)。
mysql> select @i:=@i+1 as rank, a.usernum, s.buildings from account_data as a, statistics as s join (select @i:=0) rank
where a.gamenumber=144 and a.usernum=s.usernum order by s.buildings desc limit 10;
+------+---------+-----------+
| rank | usernum | buildings |
+------+---------+-----------+
| 49 | 31071 | 87557 |
| 45 | 31047 | 86858 |
| 24 | 31064 | 84753 |
| 69 | 31089 | 79682 |
| 17 | 31103 | 76892 |
| 38 | 31106 | 66186 |
| 29 | 31053 | 65069 |
| 47 | 31081 | 59093 |
| 61 | 31036 | 58056 |
| 100 | 31061 | 56833 |
+------+---------+-----------+
10 rows in set (0.01 sec)
mysql> select @i:=@i+1 as rank, a.usernum, s.buildings from account_data as a, statistics as s join (select @i:=0) rank
where s.gamenumber=144 and a.usernum=s.usernum order by s.buildings desc limit 10;
+------+---------+-----------+
| rank | usernum | buildings |
+------+---------+-----------+
| 1 | 31071 | 87557 |
| 2 | 31047 | 86858 |
| 3 | 31064 | 84753 |
| 4 | 31089 | 79682 |
| 5 | 31103 | 76892 |
| 6 | 31106 | 66186 |
| 7 | 31053 | 65069 |
| 8 | 31081 | 59093 |
| 9 | 31036 | 58056 |
| 10 | 31061 | 56833 |
+------+---------+-----------+
10 rows in set (0.00 sec)
谁能向我解释为什么当顺序正确时排名会有所不同?
以这种方式使用变量是一种黑客:
select @i:=@i+1 as rank
如果您仅从一个表中进行选择,则可以期望此操作有效。 当您将更多表连接在一起时,MySQL可能会评估@i:=@i+1
行,该行稍后被where
子句过滤掉。
若要解决此问题,请确保在联接外部计算排名。 一种方法是将联接结果存储在一个临时表中,并计算该表的排名。