为什么这个 php 查询不起作用?
Why this php query does not work?
所以我正在为我的统一游戏制作高分系统,使用mysql、php。
为了获取存储在数据库中的高分信息,我这样写,(数据库有 'score'、'name' 列,但没有 'rank' 列名称)
$sql = "SELECT id, score, name, CASE\n"
. " WHEN @prev_value = score THEN @rank_count\n"
. " WHEN @prev_value := score THEN @rank_count := @rank_count + 1\n"
. "END AS rank\n"
. "FROM BBR\n"
. "ORDER BY score DESC LIMIT $min, $max";
$result = mysql_query($sql) or Die('Query failed: ' . mysql_error());
$info = "";
while($found = mysql_fetch_array($result)){
$info = $info .'@'. $found['name'] .':'. $found['score'] .':'. $found['rank'];
}
echo $info;
并且在统一中,我收到此信息并拆分为每个字符串。
string[] score = serverHighScores[x].Split(':');
但是这个在score[0](名字)、score[1](分数)上工作得很好,但是在score[2](排名)上不起作用。
为什么?我该如何解决?
谢谢
这个查询是
SET @prev_value = NULL;
SET @rank_count = 0;
SELECT id, score, name, CASE
WHEN @prev_value = score THEN @rank_count
WHEN @prev_value := score THEN @rank_count := @rank_count + 1
END AS rank
FROM BBR
ORDER BY score DESC
这在 phpmyadmin SQL.
中运行良好
我会这样写查询:
SELECT b.id
, b.name
, @rank_cnt := IF(@prev_score = b.score,@rank_cnt,@rank_cnt+1) AS rank
, @prev_score := b.score AS score
FROM BBR b
CROSS
JOIN ( SELECT @rank_cnt := 0, @prev_score := NULL) i
ORDER BY b.score DESC, b.id DESC
注意:我们通过此查询观察到的行为不得到保证。 MySQL 参考手册特别警告不要以这种方式使用用户定义的变量。但是我们观察到的行为(至少对于 MySQL 5.1 和 5.5)是一致的。
在比较之后完成 @prev_score
的赋值很重要,这就是为什么列在 SELECT 列表中按原样排序的原因。
我认为 CASE 表达式中的赋值(它在问题查询中的方式)"work" 与我们期望的方式不同。我认为这与 MySQL 执行的操作顺序有关。我总是将表达式的结果分配给 SELECT 列表中的用户定义变量,如上所示。
表达式 IF(@prev_score = b.score,@rank_cnt,@rank_cnt+1)
可以替换为等效的 CASE
表达式:
CASE WHEN @prev_score = b.score THEN @rank_cnt ELSE @rank_cnt+1 END
请注意,表达式 return 正在计算一个值,而不是尝试进行赋值。
我更喜欢在语句中初始化用户定义的变量,而不是依赖于单独的 SET
语句。在这种情况下,我们并不真正关心内联视图 i
编辑的内容 return,除了我们希望它正好 return 一行(因为 JOIN 操作)。 .. 我们真的更感兴趣的是内联视图查询在外部查询运行之前具体化,以便在外部查询运行时初始化变量。
此外,我在 ORDER BY 中添加了另一个表达式,使结果更具确定性。
...(将 link 添加到 MySQL 参考手册中有关用户定义变量警告的适用部分)
mysql_
接口函数已弃用。请改用 mysqli
或 PDO
界面。
所以我正在为我的统一游戏制作高分系统,使用mysql、php。
为了获取存储在数据库中的高分信息,我这样写,(数据库有 'score'、'name' 列,但没有 'rank' 列名称)
$sql = "SELECT id, score, name, CASE\n"
. " WHEN @prev_value = score THEN @rank_count\n"
. " WHEN @prev_value := score THEN @rank_count := @rank_count + 1\n"
. "END AS rank\n"
. "FROM BBR\n"
. "ORDER BY score DESC LIMIT $min, $max";
$result = mysql_query($sql) or Die('Query failed: ' . mysql_error());
$info = "";
while($found = mysql_fetch_array($result)){
$info = $info .'@'. $found['name'] .':'. $found['score'] .':'. $found['rank'];
}
echo $info;
并且在统一中,我收到此信息并拆分为每个字符串。
string[] score = serverHighScores[x].Split(':');
但是这个在score[0](名字)、score[1](分数)上工作得很好,但是在score[2](排名)上不起作用。
为什么?我该如何解决? 谢谢
这个查询是
SET @prev_value = NULL;
SET @rank_count = 0;
SELECT id, score, name, CASE
WHEN @prev_value = score THEN @rank_count
WHEN @prev_value := score THEN @rank_count := @rank_count + 1
END AS rank
FROM BBR
ORDER BY score DESC
这在 phpmyadmin SQL.
中运行良好我会这样写查询:
SELECT b.id
, b.name
, @rank_cnt := IF(@prev_score = b.score,@rank_cnt,@rank_cnt+1) AS rank
, @prev_score := b.score AS score
FROM BBR b
CROSS
JOIN ( SELECT @rank_cnt := 0, @prev_score := NULL) i
ORDER BY b.score DESC, b.id DESC
注意:我们通过此查询观察到的行为不得到保证。 MySQL 参考手册特别警告不要以这种方式使用用户定义的变量。但是我们观察到的行为(至少对于 MySQL 5.1 和 5.5)是一致的。
在比较之后完成 @prev_score
的赋值很重要,这就是为什么列在 SELECT 列表中按原样排序的原因。
我认为 CASE 表达式中的赋值(它在问题查询中的方式)"work" 与我们期望的方式不同。我认为这与 MySQL 执行的操作顺序有关。我总是将表达式的结果分配给 SELECT 列表中的用户定义变量,如上所示。
表达式 IF(@prev_score = b.score,@rank_cnt,@rank_cnt+1)
可以替换为等效的 CASE
表达式:
CASE WHEN @prev_score = b.score THEN @rank_cnt ELSE @rank_cnt+1 END
请注意,表达式 return 正在计算一个值,而不是尝试进行赋值。
我更喜欢在语句中初始化用户定义的变量,而不是依赖于单独的 SET
语句。在这种情况下,我们并不真正关心内联视图 i
编辑的内容 return,除了我们希望它正好 return 一行(因为 JOIN 操作)。 .. 我们真的更感兴趣的是内联视图查询在外部查询运行之前具体化,以便在外部查询运行时初始化变量。
此外,我在 ORDER BY 中添加了另一个表达式,使结果更具确定性。
...(将 link 添加到 MySQL 参考手册中有关用户定义变量警告的适用部分)
mysql_
接口函数已弃用。请改用 mysqli
或 PDO
界面。