Report Card Query in MySQL
In this lesson: Build a student report card with SQL — total marks, percentage, grade with CASE and rank — full query and output. In Hindi & English.
A real report card
A report card query is a classic school project: from a table of marks, compute each student's total, percentage, grade and pass/fail. It brings together SUM, GROUP BY and CASE — a great practical exercise.
The marks table
-- one row per student per subject +------------+---------+-------+ | student_id | subject | marks | +------------+---------+-------+ | 1 | Math | 88 | | 1 | Science | 76 | | 1 | English | 92 | +------------+---------+-------+
This normalized layout (a row per subject) makes totals and averages easy, and lets you add subjects without changing the table.
Total and percentage
SELECT student_id,
SUM(marks) AS total,
ROUND(SUM(marks) / (COUNT(*) * 100) * 100, 2) AS percent
FROM marks
GROUP BY student_id;
GROUP BY student, SUM the marks for the total, and divide by the maximum (subjects × 100) for the percentage, rounded to two places.
Grade with CASE
SELECT student_id,
SUM(marks) AS total,
CASE
WHEN SUM(marks)/(COUNT(*)*100)*100 >= 90 THEN 'A'
WHEN SUM(marks)/(COUNT(*)*100)*100 >= 75 THEN 'B'
WHEN SUM(marks)/(COUNT(*)*100)*100 >= 33 THEN 'C'
ELSE 'F'
END AS grade
FROM marks
GROUP BY student_id;
A CASE on the percentage turns the number into a letter grade, right in the query.
Pass or fail
SELECT student_id,
CASE WHEN MIN(marks) >= 33 THEN 'Pass' ELSE 'Fail' END AS result
FROM marks
GROUP BY student_id;
A student passes only if every subject is at least the pass mark. Checking MIN(marks) >= 33 catches a failure in any single subject.
Ranking students
SELECT student_id, SUM(marks) AS total,
RANK() OVER (ORDER BY SUM(marks) DESC) AS rank_no
FROM marks
GROUP BY student_id;
In MySQL 8.0+, RANK() assigns positions by total marks, giving each student their class rank. On older MySQL, just ORDER BY total DESC.
Common mistakes
- Storing all subjects in one row. Use one row per subject for easy SUM/AVG.
- Wrong percentage divisor. Divide by subjects × max marks, not a fixed number.
- Grading before pass check. A low subject can fail a high average.
- Forgetting GROUP BY. Aggregates need it to work per student.
Summary
- Store marks one row per student per subject.
- Total = SUM(marks); percentage divides by subjects × 100.
- Grade with a CASE on the percentage.
- Pass/fail uses MIN(marks) against the pass mark.
- Rank with ORDER BY total or RANK() (MySQL 8.0+).
Next, learn grouping in GROUP BY and HAVING, or build the full marksheet database project.
Frequently Asked Questions
How do I calculate total and percentage in a MySQL report card?
SUM(marks) AS total, SUM(marks)/(COUNT(*)*100)*100 AS percent. GROUP BY the student.How do I assign a grade in a report card query?
CASE WHEN percent >= 90 THEN 'A' WHEN percent >= 75 THEN 'B' ... ELSE 'F' END. This turns the numeric percentage into a letter grade in the result.How do I show pass or fail in MySQL?
CASE WHEN MIN(marks) >= 33 THEN 'Pass' ELSE 'Fail' END. A student fails if any subject is below the pass mark.How do I rank students by their total marks?
ORDER BY total DESC. For a numbered rank, use RANK() OVER (ORDER BY total DESC) in MySQL 8.0+, which gives each student a position based on their total.