为什么这个php查询不起作用?

时间:2015-04-28 03:33:31

标签: php mysql unity3d

所以我正在制作高分系统,对于我的团结游戏,使用mysql,php。

为了获得存储在DB中的高分信息,我写道,(DB有'得分','名称'列,但没有'等级'列名称)

$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(':');

但这项工作在得分[0](姓名),得分[1](得分)很好,但在得分[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中运行良好。

1 个答案:

答案 0 :(得分:3)

我会写这样的查询:

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 Reference手册特别警告不要以这种方式使用用户定义的变量。但我们观察到的行为(至少在MySQL 5.1和5.5中)是一致的。

在比较之后完成@prev_score的分配非常重要,这就是为什么列在SELECT列表中按照它们的顺序排序的原因。

我不认为CASE表达式中的赋值(它在问题中的查询方式)“按照我们期望的方式”工作。我认为这与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

请注意,表达式返回一个值,它不会尝试进行赋值。

我更喜欢在语句中初始化用户定义的变量,而不依赖于单独的SET语句。在这种情况下,我们并不真正关心内联视图i返回的内容,除了我们希望它只返回一行(因为JOIN操作)...我们真的更感兴趣的是内部视图查询在外部查询运行之前实现,以便在外部查询运行时初始化变量。

另外,我在ORDER BY中添加了另一个表达式,因此结果更具确定性。

...(添加有关用户定义变量警告的MySQL参考手册适用部分的链接)

mysql_ 接口函数已弃用。请改用mysqliPDO界面。