The idea is to
query the data, and then use group by to sort, so that we can get the grouped data, and then we customize a field in the query field in select to get its sort order, and finally add a layer to the outer layer, just get The first N pieces of data are sufficient.
example
SELECT t.*
FROM (
SELECT a.id,
a.type_id,
c.`name` AS typeName,
a.scan_total,
a.`name`,
(
SELECT COUNT(b.id)
FROM course AS b
WHERE b.type_id = a.type_id
AND b.scan_total > a.scan_total
) AS top
FROM course AS a LEFT JOIN course_type AS c
ON c.id = a.type_id
ORDER BY a.type_id ASC,
a.scan_total DESC
) AS t
WHERE t.top < 3