punji
punji

Reputation: 27

getting rank of student

I am trying to get rank of student by using total marks, that is the student with higher marks than the other should be the first and so on, I'm using while loop to do so, but when two or more student have the same total marks they get different rank, what I want to achieve is when two or more student have the same total marks they should have the same rank, please help, here is my code.

<?php require_once("include/connection.php"); ?>
<?php
$query = "SELECT * FROM `total` ORDER BY `total` DESC"; 
$result = mysql_query($query) or die(mysql_error()); 
$rank = 1; // initialize 
echo "<table><tr><th>Student Code</th><th>Rank</th><th>Total</th></tr>\n"; 
while($row = mysql_fetch_assoc($result)) 
{ 
    echo "<tr><td>{$row['student_code']}</td><td>$rank</td><td>{$row['total']}</td></tr>\n"; 
    if ($rank == 100) 
    { break; }
    $rank++; 
} 
echo "</table>\n";  
?>

Upvotes: 2

Views: 1449

Answers (4)

Its very simple I used in query [Order by marks Desc] and its display the record Rank 1 to last Rank. very Simple.

Upvotes: 0

Akshay Hegde
Akshay Hegde

Reputation: 16997

Please use mysqli_* functions mysql_* functions are very old now

<?php 
require_once("include/connection.php");
$query = "SELECT * FROM `total` ORDER BY `total` DESC"; 
$result = mysql_query($query) or die(mysql_error()); 

$rank = $previous = 0;

echo "<table><tr><th>Student Code</th><th>Rank</th><th>Total</th></tr>"; 

while($row = mysql_fetch_assoc($result)) 
{ 
    // break statement at the end has no effect since you are doing echo on top.
    if ($rank == 100)break; 

    // If same total will skip $rank++
    if($row['total'] != $previous)$rank++;

    echo "<tr><td>".$row['student_code']."</td><td>$rank</td><td>".$row['total']."</td></tr>"; 

    // Current row student's total 
    $previous = $row['total'];
} 
echo "</table>";  
?>

Upvotes: 0

Ron Dadon
Ron Dadon

Reputation: 2706

You need to consider the "total" of the student.

First of all, If you want only 100 records, you can limit it in the SQL, that will be more efficient than the break after 100 iterations of the loop:

$query = "SELECT * FROM `total` ORDER BY `total` DESC LIMIT 100";

Think that if you have 10,000 students, you will retrive 9,900 students for nothing.

Then, your while loop can be changed like this:

$rank = 1;
$lastTotal = 0;
while($row = mysql_fetch_assoc($result)) 
{ 
    echo "<tr><td>{$row['student_code']}</td><td>$rank</td><td>{$row['total']}</td></tr>\n"; 
    if ($lastTotal == 0) {
        $lastTotal = $row['total']; // First time that $lastTotal is set.
    }
    if ($lastTotal > $row['total']) {
        $lastTotal = $row['total'];
        $rank++;
    }
}

Using this, you will increase the rank only if the rank of the current student is lower than the student before him. You can remove the first if that check for the first time that $lastToal is set if you know your max total value. If so, and for example it's 100, simply set it in $lastTotal = 100, and remove the first if inside the while loop.

$rank = 1;
$lastTotal = 100;
while($row = mysql_fetch_assoc($result)) 
{ 
    echo "<tr><td>{$row['student_code']}</td><td>$rank</td><td>{$row['total']}</td></tr>\n"; 
    if ($lastTotal > $row['total']) {
        $lastTotal = $row['total'];
        $rank++;
    }
}

Upvotes: 2

mmvsbg
mmvsbg

Reputation: 3588

Keep your current code but add one more variable outside of the loop like this with one more to keep the current score:

$current_rank = 1;
$current_score = null;

Inside the loop make a check to see if the totals are the same with the one that you keep and if they are different, then assign rank to the current rank:

if ($current_score != $row['total'])
{
    $current_rank = $rank;
}

Always display the $current_rank which will change only if it's different from the previous one and at the end of each iteration, update the $current_score as well:

$current_score = $row['total'];

I hope this helps.

Upvotes: 3

Related Questions