2

I have a table which holds grades of students based on three categories. There are five grades (A,B,C,D,E) per category, so the table looks something like this:

id | cat1 | cat2 | cat3
1     A      B       A
2     D      C       D
3     B      A       E
4     C      B       D

etc

I have a second table that list the grades

grade
  A
  B
  C
  D
  E

I need to be able to run a query on this data so that I can count the number of grades achieved in each category for each grade. Something like this:

    Cat1 | Cat2 | Cat 3
A     1     1      1
B     1     2      0
C     1     1      0
D     1     0      2
E     0     0      1

I have ran the following query, which I know is not correct, but is yielding results close to expected:

SELECT g.grade, COUNT( mb.cat1) , COUNT( mb.cat2) , COUNT( mb.cat3)
FROM markbook mb, grades g
WHERE g.grade = mb.cat1
GROUP BY g.grade
0

2 Answers 2

2

Try:

SELECT g.grade, 
       COUNT(case mb.cat1 when g.grade then 1 end), 
       COUNT(case mb.cat2 when g.grade then 1 end), 
       COUNT(case mb.cat3 when g.grade then 1 end)
FROM markbook mb
cross join grades g
GROUP BY g.grade

(SQLFiddle here)

Sign up to request clarification or add additional context in comments.

Comments

2

While I know an answer has been picked already, the way I would have gone for this would be to use LEFT JOIN, so that if a grade had no matches it would still show up. Example as follows:

SELECT 

  g.grade,
  SUM(CASE mb.cat1 WHEN g.grade THEN 1 ELSE 0 END) AS cat1,
  SUM(CASE mb.cat2 WHEN g.grade THEN 1 ELSE 0 END) AS cat2,
  SUM(CASE mb.cat3 WHEN g.grade THEN 1 ELSE 0 END) AS cat3

FROM grades g
LEFT JOIN markbook mb 
    ON g.grade IN (mb.cat1,mb.cat2,mb.cat3)
GROUP BY g.grade;

(SQL fiddle example, schema borrowed from Mark Bannisters answer : http://sqlfiddle.com/#!2/9b863/1 )

2 Comments

The use of a cross join in my query ensures that a grade with no matches will still appear in mine, too - see sqlfiddle.com/#!2/9b863/2 .
I see, I thought it would have behaved more like INNER JOIN. Well, you learn something new every day :) This kind of query has never really cropped up in what I tend to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.