如何通过另一列mysql查找邻居顺序

时间:2014-10-01 03:25:08

标签: php mysql

我的问题是,

我在mysql中有一个表

哪个列是

  id   Student   score  
  1     A         55 
  2     B         86
  3     C         65
  4     D         23
  5     E         84
  6     F         45
  7     G         80

我希望根据分数找到全班同学的等级,其中得分更高的学生和另一名得分更低的学生。 例如,如果我正在寻找学生E

然后输出

   id   User   score  rank_in_classs
    2    B      86         1
    5    E      84         2
    7    G      80         3

另一个例子是,如果我正在寻找学生A

   id   User   score  rank_in_classs
    3    c      65         4
    1    A      55         5
    6    F      45         6

如何使用mysql查询找到它。

由于

3 个答案:

答案 0 :(得分:1)

<强>查询

SELECT id, Student, score, 
FIND_IN_SET( score, (    
SELECT GROUP_CONCAT( score
ORDER BY score DESC ) 
FROM tbl )
) AS rank_in_class
FROM tbl
ORDER BY rank_in_class
LIMIT 3;

DEMO

答案 1 :(得分:0)

使用Ullas提出的基于FIND_IN_SET()的解决方案,您可以通过这种方式找到特定学生+/- 1级别:

set @this_rank := (
                    SELECT
                          FIND_IN_SET( score, (    
                                                SELECT GROUP_CONCAT( score
                                                ORDER BY score DESC ) 
                                                FROM tbl 
                                                )
                                     ) AS rank_in_class
                    FROM tbl
                    where student = 'A'
                    );
select
*
from (
      SELECT
            id
          , Student
          , score
          , FIND_IN_SET( score, (    
                                  SELECT GROUP_CONCAT( score
                                  ORDER BY score DESC ) 
                                  FROM tbl 
                                  )
                       ) AS rank_in_class
      FROM tbl
     ) ric
where rank_in_class between @this_rank-1 AND @this_rank+1
ORDER BY rank_in_class
LIMIT 3;

注意: IF 您将排名值存储在表格中,这样就不会那么繁琐,并且可以更好地执行。

答案 2 :(得分:0)

最好的方法可能是混合使用两个查询和一些PHP。

  • 第一个查询检索&#34;焦点&#34;的排名。你想要的学生;
  • 第二个查询检索焦点&#34;学生周围所有学生的范围&#34;使用动态LIMIT语句(这是PHP的使用不可避免的地方);

所以这样的事情可能会起作用:

$user = 'C'; // Student user we want to "focus"
$range = 1; // Range around the "focus" : 1 before and 1 after (could be changed to anything else)

// First query : retrieving the rank of the "focused" student
$stmt = $mysqli->prepare('SELECT COUNT(*) AS Rank FROM Student AS Focused INNER JOIN Student as Others ON Others.Score > Focused.Score OR (Others.Score = Focused.Score AND Others.Id > Focused.Id) WHERE Focused.user = ?');
$stmt->bind_param('s',$user);
$stmt->execute();
$res = $stmt->get_result()->fetch_assoc();
$startRank = $res['Rank'];

// Computing the dynamic LIMIT
if (($startRank - $range) < 1) {
  $offset = 0;
  $rowCount = $startRank + $range + 1;
} else {
  $offset = $startRank - $range;
  $rowCount = ($range * 2)+1;
}

// Second query : retrieving the rank of all the students around the "focused" student
$stmt = $mysqli->prepare('SELECT id, user, score, @curRank := @curRank + 1 AS rank FROM Student, (SELECT @curRank := ?) Rank ORDER BY Score DESC, id DESC LIMIT ?, ?');
$stmt->bind_param('iii',$offset,$offset,$rowCount);
$stmt->execute();

这可能是查询数据库以获得所需内容的最佳方式。作为奖励,您可以将范围更改为您喜欢的任何范围。