I would like to take values from one table column and subtract those values from another column from another table.
I was able to achieve this by joining those tables and then subtracting both columns from each other.
Data from first table:
SELECT max_participants FROM courses ORDER BY id;
Data from second table:
SELECT COUNT(id) FROM participations GROUP BY course_id ORDER BY course_id;
Here is some code:
SELECT max_participants - participations AS free_places FROM ( SELECT max_participants, COUNT(participations.id) AS participations FROM courses INNER JOIN participations ON participations.course_id = courses.id GROUP BY courses.max_participants, participations.course_id ORDER BY participations.course_id ) AS course_places;
In general, it works, but I was wondering, if there is some way to make it simplier or maybe my approach isn’t correct and this code will not work in some conditions? Maybe it needs to be optimized.
I’ve read some information about not to rely on natural order of result set in databases and that information made my doubts to appear.
Advertisement
Answer
If you want the values per course, I would recommend:
SELECT c.id, (c.max_participants - COUNT(p.id)) AS free_places FROM courses c LEFT JOIN participations p ON p.course_id = c.id GROUP BY c.id, c.max_participants ORDER BY 1;
Note the LEFT JOIN
to be sure all courses are included, even those with no participants.
The overall number is a little tricker. One method is to use the above as a subquery. Alternatively, you can pre-aggregate each table:
select c.max_participants - p.num_participants from (select sum(max_participants) as max_participants from courses) c cross join (select count(*) as num_participants from participants from participations) p;