【问题标题】:Can someone explain why this select statement behaves the way it does有人可以解释为什么这个 select 语句的行为方式是这样的吗
【发布时间】:2012-06-15 03:34:48
【问题描述】:

在为游戏生成排名时,我编写了一个类似于以下代码的查询(为简洁起见,省略了很多列),并注意到排名产生的似乎是乱码(第一个查询)。但是,更改引用 gamenumber 的表会产生正确的结果(第二个查询)。

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)

谁能向我解释为什么顺序正确时排名结果不同?

【问题讨论】:

    标签: sql mysql4


    【解决方案1】:

    以这种方式使用变量有点像 hack:

    select @i:=@i+1 as rank
    

    如果您只从一个表中进行选择,您可能会认为这会起作用。当您将更多表连接在一起时,MySQL 可能会评估 @i:=@i+1 以获取稍后被 where 子句过滤掉的行。

    要解决此问题,请确保在连接之外计算排名。一种方法是将连接结果存储在临时表中,然后计算其排名。

    【讨论】:

    • 临时表不会飞。大约有 15 个排名,然后对于付费客户,这些用户的实际排名。
    • 有其他计算排名的方法吗?
    • 您可以毫无问题地即时创建数千个临时表。事实上,MySQL 使用临时表的原因有很多,无论您是否要求。有其他方法,但与 @i:=@i+1 技巧相比,它们非常昂贵。
    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2020-02-23
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多