Возможно, вы можете отфильтровать 'неправильное' уже в предложении WHERE
.
Тогда не вернутся те, которые имеют только «правильное».
Но поскольку вам нужны только те, у которых максимальное «не правильное» значение должно быть достаточно справедливым.
И вам также может понадобиться выбрать только те, которые должны были быть возвращены до текущей даты.
SELECT c.course_code, c.course_name
, COUNT(DISTINCT bb.pupil_id) AS non_correct_pupils
FROM books_out_on_loan bb
INNER JOIN pupils_on_courses ps
ON ps.pupil_id = bb.pupil_id
INNER JOIN courses c
ON c.course_code = ps.course_code
WHERE bb.date_to_return < CAST(current_timestamp AS DATE)
AND (bb.date_returned IS NULL OR bb.date_returned > bb.date_to_return)
GROUP BY c.course_code, c.course_name
ORDER BY COUNT(DISTINCT bb.pupil_id) DESC
DISTINCT используется для подсчета только уникальных идентификаторов pupil.
Чтобы получить самый высокий рейтинг, попробуйте это
SELECT *
FROM
(
SELECT c.course_code, c.course_name
, COUNT(DISTINCT bb.pupil_id) AS non_correct_pupils
, DENSE_RANK() OVER (ORDER BY COUNT(DISTINCT bb.pupil_id) DESC) AS Rnk
FROM books_out_on_loan bb
INNER JOIN pupils_on_courses ps
ON ps.pupil_id = bb.pupil_id
INNER JOIN courses c
ON c.course_code = ps.course_code
WHERE bb.date_to_return < CAST(current_timestamp AS DATE)
AND (bb.date_returned IS NULL OR bb.date_returned > bb.date_to_return)
GROUP BY c.course_code, c.course_name
)
WHERE Rnk = 1