我真的需要帮助创建一个函数,从用户的最高得分计算排名。我在这里看到了很多如何查询MYSQL的例子,但我没有足够的PHP知识来创建函数。
我有一张桌子:
PRIMARY
blogs_id users_id blogs_score blogs_rate_time
1 23 1872 2015-09-09 05:21:51
2 23 2146 2015-09-10 07:31:54
3 23 2146 2015-09-10 07:32:26
4 23 2852 2015-09-10 04:42:15 <-- same score but date older
5 51 1793 2015-09-11 08:15:55
6 88 2852 2015-09-11 09:33:18 <-- same score but date newer
我需要一个PHP函数来显示特定用户在其个人资料中的排名。例如,在用户id为23的用户配置文件页面中显示"2个位置",对于id为88的用户显示"1个位置"等。
我添加了列blogs_rate_time
以防止并列。
如何为此创建函数?
function blogsRate($user_id) {
global $db;
sql ="
WHAT IS THE OPTIMIZED QUERY FOR THAT?
";
$rank_query = $db->query($sql);
HERE SUPPOSE TO BE foreach I guess?
return ?;
}
我正在使用smarty来显示结果:
$smarty->assign('rank_place', $users->blogsRate($userID));
请帮我创建工作函数来解决这个问题。我非常感谢完整的函数,而不仅仅是mysql查询或函数的一部分。我是新手
提前感谢!
您可以按blogs_score和blogs_rate_time对查询进行排序,并相应地对行进行编号以获得费率。我看不到您的表名,所以我将其称为Ranks,查询如下所示。
Set @rowNumber = 0;
Select user_id, (@rowNumber := @rowNumber + 1) As Rank From Ranks
Order By blogs_score Desc, blogs_rate_time Asc;
那么你的函数应该如下所示。
function blogsRate($user_id) {
global $db;
sql ="Set @rowNumber = 0;
Select user_id, (@rowNumber := @rowNumber + 1) As Rank From Ranks
Order By blogs_score Desc, blogs_rate_time Asc;";
$rank_query = $db->query($sql);
while ($row = $rank_query->fetch_assoc()) {
if ($row['user_id'] == $user_id) {
return $row['Rank'];
}
}
return null; // Or something else that you can capture for not found
}
然而,这需要检索和迭代所有数据,因此在资源使用方面非常昂贵。为了解决这个问题,我们可以在数据库中运行搜索,只得到相关的结果。为了实现这一点,首先我们将生成排名的查询放在子查询中,并在该子查询中进行搜索,如下所示。
Set @rowNumber = 0;
Select * From (
Select user_id, (@rowNumber := @rowNumber + 1) As Rank From Ranks
Order By blogs_score Desc, blogs_rate_time Asc
) T Where user_id = $user_id Limit 1;
Limit 1将只选择第一个结果,这应该是该user_id的最佳排名,因为我看到一个用户可能有多个排名。为了只为每个用户获得最佳排名,我们需要添加另一个子查询,该子查询只提供最佳分数和时间。
Select * From (
Select user_id, (@rowNumber := @rowNumber + 1) As Rank
From (
Select user_id, MAX(blogs_score) blogs_score,
MAX(blogs_rate_time) blogs_rate_time
From Ranks
Group By user_id
) G
Order By blogs_score Desc, blogs_rate_time Desc
) T Where user_id = $user_id;
你的功能应该像这个
function blogsRate($user_id) {
global $db;
sql ="Set @rowNumber = 0;
Select * From (
Select user_id, (@rowNumber := @rowNumber + 1) As Rank
From (
Select user_id, MAX(blogs_score) blogs_score,
MAX(blogs_rate_time) blogs_rate_time
From Ranks
Group By user_id
) G
Order By blogs_score Desc, blogs_rate_time Desc
) T Where user_id = $user_id";
$rank_query = $db->query($sql);
if ($rank_query->num_rows > 0) {
$row = $rank_query->fetch_assoc();
return $row['Rank'];
}
else return null;
}
SQL Fiddle:http://sqlfiddle.com/#!9/149023/11
$sql = '
SET @rank=0;
SELECT *
FROM (
SELECT @rank:=@rank+1 AS rank, blogs_id, users_id, blogs_score, blogs_rate_time
FROM YOUR_TABLE_NAME
ORDER BY blogs_score DESC, blogs_rate_time ASC
) AS sub_query_table
WHERE users_id = ' . $user_id;
这应该奏效。它会给你一个唯一的结果,当然,除非你有多个user_id。MySQL在数据库排序方面比PHP快。
我不知道你的$db是什么,但我想它会返回一个数组,这样你就可以用之类的东西来获取值
返回$rank_query[0]。