I have the following database schema. My goal is to obtain a result set that lists the total badge points earned by each user. The badges might be earned in different courses. I want to include the courseid and the average score per course.
Users table:
| id | username |
|----|----------|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
Badges table:
| id | badgename | points | courseid |
|----|-----------|--------|----------|
| 1 | badge a | 15 | 1 |
| 2 | badge b | 10 | 1 |
| 3 | badge c | 20 | 1 |
| 4 | badge d | 15 | 2 |
| 5 | badge e | 10 | 2 |
| 6 | badge f | 25 | 2 |
BadgeAssignments table:
| userid | badgeid |
|--------|---------|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 1 | 4 |
| 2 | 5 |
| 3 | 6 |
| 1 | 5 |
| 2 | 4 |
| 3 | 3 |
Courses table:
| courseid | coursename |
|----------|------------|
| 1 | course 1 |
| 2 | course 2 |
I have ended up with the following code, and I think it works fine:
SELECT userid, SUM(b.points), courseid,
(SELECT AVG(points) FROM Badges WHERE courseid = b.courseid) as courseAVG
FROM
Badges b INNER JOIN BadgeAssignments ba ON b.id = ba.badgeid
INNER JOIN Users u ON ba.userid = u.id
GROUP BY userid, b.courseid
which brings me this result:
| userid | SUM(b.points) | courseid | courseAVG |
|--------|---------------|----------|-----------|
| 1 | 15 | 1 | 15 |
| 1 | 25 | 2 | 16.6667 |
| 2 | 10 | 1 | 15 |
| 2 | 25 | 2 | 16.6667 |
| 3 | 40 | 1 | 15 |
| 3 | 25 | 2 | 16.6667 |
The numbers seem to be correct. I wonder if my query makes sense? and if it needs to be revised?
Here is the SQL Fiddle.
Badges
twice to get the individual and the average points. Two remarks: You should add an alias toSUM(b.points)
and there's no Primary Key in theBadgeAssignments
table, the same user can get the same batch more than once? \$\endgroup\$