?! Repeating multiple post texts obscures more than it clarifies.
A solution, though, needs general rules that could generate it.
One rule I've been missing under your details is:
`score` values are to be evaluated within groups of `class` values
ie this is the Top N Per Group problem.
Indeed your starting query looks a lot like the first (unscalable) solution at
http://www.artfulsoftware.com/queries.php under "Within-group quotas (Top N per group)".
For others reading along, given this DDL...
DROP TABLE IF EXISTS test;
CREATE TABLE test( id INT, entrydate DATE );
INSERT INTO test VALUES
( 1, '2007-5-01' ),( 1, '2007-5-02' ),( 1, '2007-5-03' ),( 1, '2007-5-04' ),
( 1, '2007-5-05' ),( 1, '2007-5-06' ),( 2, '2007-6-01' ),( 2, '2007-6-02' ),
( 2, '2007-6-03' ),( 2, '2007-6-04' ),( 3, '2007-7-01' ),( 3, '2007-7-02' ),( 3, '2007-7-03' );
{/code]
the Top N Per Group question is, what query gives the earliest two entrydates per ID?
SELECT tmp.ID, tmp.entrydate
FROM (
SELECT
ID, entrydate,
IF( @prev <> ID, @rownum := 1, @rownum := @rownum+1 ) AS rank,
@prev := ID
FROM test t
JOIN (SELECT @rownum := NULL, @prev := 0) AS r
ORDER BY t.ID
) AS tmp
WHERE tmp.rank <= 2
ORDER BY ID, entrydate;
+------+------------+
| ID | entrydate |
+------+------------+
| 1 | 2007-05-01 |
| 1 | 2007-05-02 |
| 2 | 2007-06-03 |
| 2 | 2007-06-04 |
| 3 | 2007-07-01 |
| 3 | 2007-07-02 |
+------+------------+
Touching up this example to get top 3 per class from your hwdata table gives ...
SELECT tmp.class, tmp.rank, entrynum, tmp.score
FROM (
SELECT
class, entrynum, score,
IF( @prev <> class, @rownum := 1, @rownum := @rownum+1 ) AS rank,
@prev := class
FROM hwdata d
JOIN (SELECT @rownum := NULL, @prev := 0) AS r
ORDER BY class, score desc
) AS tmp
WHERE tmp.rank <= 3
ORDER BY class, rank;
+-----------------------+------+----------+-------+
| class | rank | entrynum | score |
+-----------------------+------+----------+-------+
| FULL SIZE GM 07 - UP | 1 | 1 | 84.0 |
| FULL SIZE GM 07 - UP | 2 | 3 | 59.5 |
| FULL SIZE GM 07 - UP | 3 | 4 | 62.0 |
| FULL SIZE GM 88 to 06 | 1 | 2 | 17.5 |
| FULL SIZE GM 88 to 06 | 2 | 5 | 88.5 |
| FULL SIZE GM 88 to 06 | 3 | 7 | 59.5 |
+-----------------------+------+----------+-------+
A Where clause screws up the counting vars, so your specific exclusion fiddles need to be hidden
from that level, in the definition of the alias `d`.
One could write a complicated Left Join to awards in there, which obviously you're free to do,
But to show the general solution, better for a forum like this, I've just used hwdata columns ...
SELECT tmp.class, tmp.rank, entrynum, tmp.score
FROM (
SELECT
d.class, d.entrynum, d.score,
IF( @prev <> class, @rownum := 1, @rownum := @rownum+1 ) AS rank,
@prev := class
FROM (SELECT * from hwdata where award NOT LIKE '%Best of%' AND Length(dsqreason)=0) d
JOIN (SELECT @rownum := NULL, @prev := 0) AS r
ORDER BY d.class, score desc
) AS tmp
WHERE tmp.rank <= 3
ORDER BY class, rank;
+-----------------------+------+----------+-------+
| class | rank | entrynum | score |
+-----------------------+------+----------+-------+
| FULL SIZE GM 07 - UP | 1 | 1 | 84.0 |
| FULL SIZE GM 07 - UP | 2 | 4 | 62.0 |
| FULL SIZE GM 07 - UP | 3 | 6 | 61.0 |
| FULL SIZE GM 88 to 06 | 1 | 8 | 65.0 |
| FULL SIZE GM 88 to 06 | 2 | 7 | 59.5 |
+-----------------------+------+----------+-------+
If there are more fiddles, you can see where to add them.