mysql 单个用户排名
mysql ranking for a single user
我正在使用 Daniel Vassallo here 的建议对我的 mysql table.
中的条目进行排名
该建议不涉及平局,这就是我想要的方式,因为在我的记分牌上,较新的条目不会比具有相同分数的旧条目获得更高的排名,它可以满足我的需要。
我的问题是我希望能够使用这种类型的排名来获得单个用户的排名。因此,根据这个查询的输出,我想定义一个名称,以便脚本 returns 只有该用户的等级、名称和分数。
我尝试了很多不同的方法,因为其中一些方法处理关系,所以单个用户的结果最终与下面代码的结果中显示的不同。
您的帮助将不胜感激....为此变得灰暗!
这是我当前的代码:
它当前输出:
名次得分
- 我1111
- 我1111
你1110
<?php
include("common.php");
$link=dbConnect();
$limit = safe($_POST['limit']);
$query = "SELECT name, score, @curRank := @curRank + 1 AS rank
FROM $dbName . `scores`, (
SELECT @curRank := 0
) q
ORDER BY score DESC LIMIT $limit";
$result = mysql_query($query);
$my_err = mysql_error();
if($result === false || $my_err != '')
{
echo "";
}
$num_results = mysql_num_rows($result);
for($i = 0; $i < $num_results; $i++)
{
$row = mysql_fetch_array($result);
echo $row[rank] . " ". $row['name'] . " - " . $row['score'] . "\n";
}
?>
更新
澄清联系;无论关系如何,原始脚本总是会递增这就是我想要的,因为我不想要它所以关系排名相同(没有联合位置)而且恰好脚本将有利于第一个实现的人得分,这样新玩家就无法以相同的分数击败 him/her,他们必须击败它。
我知道这已被弃用,正如我在分配的类似帖子中看到的那样,但我只是想在将肉添加到骨头之前构建骨架。
正如 Spencer7593 所建议的那样,到目前为止,我已经尝试了以下代码,但运气不佳。
<?php
include("common.php");
$link=dbConnect();
$limit = safe($_POST['limit']);
$query = "SELECT name, score, @curRank := @curRank + 1 AS rank
FROM $dbName . `scores`, (
SELECT @curRank := 0
) q
ORDER BY score DESC LIMIT $limit";
$result = mysql_query($query);
$my_err = mysql_error();
if($result === false || $my_err != '')
{
echo "";
}
$num_results = mysql_num_rows($result);
while ($row = $result->fetch_assoc()) {
if ( $row['rank'] == 'you' )
{
// output this row because it's for the specified user
echo $row['name'];
}
else
{
continue;
}
}
?>
要获得从查询结果中提取的单个用户的排名,您可以 运行 通过 PHP 中的结果,就像您正在做的那样,但是 "skip" 的输出不属于指定用户的行。
不需要 for ($i=0;i<
循环。使用 "while fetch" 循环。 (我不愿意给你任何使用已弃用的 mysql 接口的示例代码;新开发应该使用 mysqli 或 PDO。)
while ($row = $result->fetch_assoc()) {
if ( $row['name'] == 'you' ) {
// output this row because it's for the specified user
echo $row['rank'];
} else {
// skip this row
}
}
您在处理 "ties" 时发出了一些声音,但不清楚您实际想要的输出是什么。如果您希望具有相同“score
”值的行具有相同的 rank
值,只需在您的查询中处理即可。如果当前行的分数与上一行的分数相匹配,则不要增加排名。例如
SELECT @curRank := IF(s.score=@prev,@curRank,@curRank + 1) AS rank
, s.name
, @prev := s.score AS score
FROM $dbName . `scores` s
CROSS
JOIN (SELECT @curRank := 0, @prev := NULL) q
ORDER BY s.score DESC
LIMIT $limit
在 SQL 文本中包含潜在的不安全值会导致 SQL 注入漏洞;我们假设您已保证 $dbName
和 $limit
的值是 safe.
如果您希望查询过滤掉特定 name
的行,则将该查询包装在括号中并将其作为内联视图引用,例如
SELECT v.rank
, v.name
, v.score
FROM ( SELECT @curRank := IF(s.score=@prev,@curRank,@curRank + 1) AS rank
, s.name
, @prev := s.score AS score
FROM $dbName . `scores` s
CROSS
JOIN (SELECT @curRank := 0, @prev := NULL) q
ORDER BY s.score DESC
LIMIT $limit
) v
WHERE v.name = 'you'
ORDER BY v.rank ASC
我正在使用 Daniel Vassallo here 的建议对我的 mysql table.
中的条目进行排名该建议不涉及平局,这就是我想要的方式,因为在我的记分牌上,较新的条目不会比具有相同分数的旧条目获得更高的排名,它可以满足我的需要。
我的问题是我希望能够使用这种类型的排名来获得单个用户的排名。因此,根据这个查询的输出,我想定义一个名称,以便脚本 returns 只有该用户的等级、名称和分数。
我尝试了很多不同的方法,因为其中一些方法处理关系,所以单个用户的结果最终与下面代码的结果中显示的不同。
您的帮助将不胜感激....为此变得灰暗!
这是我当前的代码:
它当前输出:
名次得分
- 我1111
- 我1111
你1110
<?php include("common.php"); $link=dbConnect(); $limit = safe($_POST['limit']); $query = "SELECT name, score, @curRank := @curRank + 1 AS rank FROM $dbName . `scores`, ( SELECT @curRank := 0 ) q ORDER BY score DESC LIMIT $limit"; $result = mysql_query($query); $my_err = mysql_error(); if($result === false || $my_err != '') { echo ""; } $num_results = mysql_num_rows($result); for($i = 0; $i < $num_results; $i++) { $row = mysql_fetch_array($result); echo $row[rank] . " ". $row['name'] . " - " . $row['score'] . "\n"; } ?>
更新
澄清联系;无论关系如何,原始脚本总是会递增这就是我想要的,因为我不想要它所以关系排名相同(没有联合位置)而且恰好脚本将有利于第一个实现的人得分,这样新玩家就无法以相同的分数击败 him/her,他们必须击败它。
我知道这已被弃用,正如我在分配的类似帖子中看到的那样,但我只是想在将肉添加到骨头之前构建骨架。
正如 Spencer7593 所建议的那样,到目前为止,我已经尝试了以下代码,但运气不佳。
<?php
include("common.php");
$link=dbConnect();
$limit = safe($_POST['limit']);
$query = "SELECT name, score, @curRank := @curRank + 1 AS rank
FROM $dbName . `scores`, (
SELECT @curRank := 0
) q
ORDER BY score DESC LIMIT $limit";
$result = mysql_query($query);
$my_err = mysql_error();
if($result === false || $my_err != '')
{
echo "";
}
$num_results = mysql_num_rows($result);
while ($row = $result->fetch_assoc()) {
if ( $row['rank'] == 'you' )
{
// output this row because it's for the specified user
echo $row['name'];
}
else
{
continue;
}
}
?>
要获得从查询结果中提取的单个用户的排名,您可以 运行 通过 PHP 中的结果,就像您正在做的那样,但是 "skip" 的输出不属于指定用户的行。
不需要 for ($i=0;i<
循环。使用 "while fetch" 循环。 (我不愿意给你任何使用已弃用的 mysql 接口的示例代码;新开发应该使用 mysqli 或 PDO。)
while ($row = $result->fetch_assoc()) {
if ( $row['name'] == 'you' ) {
// output this row because it's for the specified user
echo $row['rank'];
} else {
// skip this row
}
}
您在处理 "ties" 时发出了一些声音,但不清楚您实际想要的输出是什么。如果您希望具有相同“score
”值的行具有相同的 rank
值,只需在您的查询中处理即可。如果当前行的分数与上一行的分数相匹配,则不要增加排名。例如
SELECT @curRank := IF(s.score=@prev,@curRank,@curRank + 1) AS rank
, s.name
, @prev := s.score AS score
FROM $dbName . `scores` s
CROSS
JOIN (SELECT @curRank := 0, @prev := NULL) q
ORDER BY s.score DESC
LIMIT $limit
在 SQL 文本中包含潜在的不安全值会导致 SQL 注入漏洞;我们假设您已保证 $dbName
和 $limit
的值是 safe.
如果您希望查询过滤掉特定 name
的行,则将该查询包装在括号中并将其作为内联视图引用,例如
SELECT v.rank
, v.name
, v.score
FROM ( SELECT @curRank := IF(s.score=@prev,@curRank,@curRank + 1) AS rank
, s.name
, @prev := s.score AS score
FROM $dbName . `scores` s
CROSS
JOIN (SELECT @curRank := 0, @prev := NULL) q
ORDER BY s.score DESC
LIMIT $limit
) v
WHERE v.name = 'you'
ORDER BY v.rank ASC