I have a query :
select score, count(1) as 'NumStudents' from testresults where testid = 'mytestid'
group by score order by score
where testresults table contains the performances of students in a test. A sample result looks like the following, assuming maximum marks of the test is 10.
score, NumStudents
0 10
1 20
2 12
3 5
5 34
..
10 23
As you can see, this query does not return any records for scores which no student have scored. For eg. nobody scored 4/10 in the test and there are no records for score = 4 in the query output.
I would like to change the query so that I can get these missing records with 0 as the value for the NumStudents field. So that my end output would have max + 1 records, one for each possible score.
Any ideas ?
EDIT:
The database contains several tests and the maximum marks for the test is part of the test definition. So having a new table for storing all possible scores is not feasible. In the sense that whenever I create a new test with a new max marks, I need to ensure that the new table should be changed to contain these scores as well.
解决方案
SQL is good at working with sets of data values in the database, but not so good at sets of data values that are not in the database.
The best workaround is to keep one small table for the values you need to range over:
CREATE TABLE ScoreValues (score int);
INSERT INTO ScoreValues (score)
VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
Given your comment that you define the max marks of a test in another table, you can join to that table in the following way, as long as ScoreValues is sure to have values at least as high or higher than the greatest test's max marks:
SELECT v.score, COUNT(tr.score) AS 'NumStudents'
FROM ScoreValues v
JOIN Tests t ON (v.score <= t.maxmarks)
LEFT OUTER JOIN TestResults tr ON (v.score = tr.score AND t.testid = tr.testid)
WHERE t.testid = 'mytestid'
GROUP BY v.score;