PHP函数用于显示来自用户时间戳的最高得分的排名

时间:2015-09-11 15:56:08

标签: php mysql

我真的需要帮助来创建一个函数来从用户的最高分计算排名。我在这里看到了很多关于如何查询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查询或函数的一部分。我是新手

提前多多感谢!

2 个答案:

答案 0 :(得分:3)

您可以通过blogs_score和blogs_rate_time订购查询,并相应地对您的行进行编号以获得费率。我看不到你的表名,所以我只称它为排名,查询如下所示。

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;

限制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小提琴:http://sqlfiddle.com/#!9/49023/11

答案 1 :(得分:0)

$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]。