【问题标题】:Group and Rank Rows in Mysql在 Mysql 中对行进行分组和排名
【发布时间】:2010-11-12 17:07:41
【问题描述】:

我正在尝试在 mysql 数据库中构建排名系统。

我在 StackOverflow 上找到了几个关于排名和项目的教程,这些教程是关于对各个行进行相互排名的。

但是,我的问题是我需要按用户 ID 列对行进行分组,将这些值添加到按用户 ID 分组的第二列,然后将它们与不同用户 ID 的其他组进行排名。

这是我正在使用的表格的示例:

user_id  km_skied  date_entered
1        34        2010-08-19
3        2         2010-08-23
1        3         2010-08-13
4        23        2010-08-01
3        5         2010-08-02

结果打印输出将按等级排列:

滑雪等级:

排名用户 ID 总公里数 1 1 37 2 4 23 3 3 7

另外,我想知道如何找到特定用户的排名。意思是,如果我知道用户 ID 是什么,我可以只给他们排名吗?喜欢说

“您的排名:2 of 345”

这是本文的第二部分。

有人知道怎么做吗? 谢谢! 特洛伊

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    您的查询应如下所示。将排名逻辑添加到外循环。

    select * from 
        (select user_id, sum(km_skied) as km from ski group by user_id) x
    order by x.km desc;
    

    不知道是不是一个选项,但是你可以使用临时表进行排名如下:

    create temporary table ranks (rank int primary key auto_increment, user_id int, km int);
    
    insert into ranks (user_id, km) 
        select user_id, km from (
            select user_id, sum(km_skied) as km from ski group by user_id
        ) x order by x.km desc;
    

    这会给你你想要的:

    mysql> select * from ranks;
    +------+---------+------+
    | rank | user_id | km   |
    +------+---------+------+
    |    1 |       1 |   37 |
    |    2 |       4 |   23 |
    |    3 |       3 |    7 |
    +------+---------+------+
    3 rows in set (0.00 sec)
    

    这种方法的一个缺点是,并列的滑雪者不会获得相同的排名。

    【讨论】:

      【解决方案2】:

      在子查询中进行分组并在外部查询中对结果进行排名(使用您之前找到的任何方法)。

      【讨论】:

      • 这需要在子查询中使用 ORDER BY,这是没有意义的,因为关系 应该 是集合(根据定义无序)。但遗憾的是,我不知道 MySQL 有什么其他方法。
      • 我确实找到了第一部分的解决方案,按组排序使用:"SELECT SUM(track_length) as usertracklength, username, MAX(track_create_time) as lasttrack, count(DISTINCT track_create_time) as totaldays FROM mv_user_tracks GROUP BY username ORDER BY usertracklength DESC"; 然后使用 PHP 将结果打印在有序列表中。我需要找到的是个人的排名,这样我就可以打印出类似“你的排名:100 分中的 2 分”之类的内容。
      【解决方案3】:

      感谢你们的帮助。 我能够根据以下查询提出答案:

      $totalQuery = "SELECT SUM(track_length) as usertracklength, username, MAX(track_create_time) as lasttrack, count(DISTINCT track_create_time) as totaldays FROM user_tracks GROUP BY username ORDER BY usertracklength DESC";
      $totalResult = mysql_query($totalQuery);
      $rankResult = mysql_query($totalQuery);
      $totalNumEntries = mysql_num_rows($totalResult);
      

      然后将其输出到数组中

      // rank position array
      $rankArray = array();
      
      while ($row1 = mysql_fetch_array($rankResult)) {
          $rankArray[] = $row1['username'];
      }
      

      然后在 php 中使用 foreach 查找该用户名在数组中的位置

      foreach ($rankArray as $rank => $user) {
          if ($user == $username) {
          $yourRank = $rank+1; 
          }
      }
      

      这是很长的路要走,但我想它适用于我的目标。 有点希望在 mysql 查询中完成它以提高效率。

      谢谢!

      【讨论】:

        【解决方案4】:

        您可以尝试将 Km 作为第一个查询进行分组,然后通过相关的子查询来查找排名。例如,如果您的值存储在名为“test”的表中,则将 Km 值汇总到名为 testtbl 的表中,然后进行排名。

        mysql> select * from test; +--------+--------+------+ |身份证 |公里运行 |姓名 | +--------+--------+------+ | 1 | 34 |一个 | | 3 | 2 | c | | 1 | 3 |一个 | | 4 | 23 | d | | 3 | 5 | c | +--------+--------+------+ 一组 5 行(0.00 秒)

        mysql> 创建表 testtbl 为 (选择Id,sum(km_run)作为tot 从测试 按 ID 分组);

        查询正常,3 行受影响(0.04 秒) 记录:3 重复:0 警告:0

        mysql> select * from testtbl; +------+------+ |身份证 |总| +------+------+ | 1 | 37 | | 3 | 7 | | 4 | 23 | +------+------+ 3 行一组(0.00 秒)

        mysql> 选择 t1.Id,t1.tot, ((select count(distinct t2.tot) from testtbl t2 where t1.tot

        【讨论】:

          猜你喜欢
          • 2010-10-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-24
          • 1970-01-01
          相关资源
          最近更新 更多