In this answer, I call "Best" to choose any choice that has selected the right winner for a particular match and has the closest result to the actual score of the match.
These scenarios also respect the various “rounds” in the contest, as this is an important complication.
This answer consists of two parts: first, a query similar to the query in the question, which returns all the "best" options for a particular match. To make it easier to run in SQL Fiddle, I used MySQL variables instead of PHP variables.
Scheme with test data:
create table Multiple_Picks ( pick_id int, member_nr int, event_id int, pick varchar(100), score int ); insert into Multiple_Picks values (11,100,1,'Crusaders',15), (12,100,2,'Waratahs',10), (13,100,3,'Chiefs',4), (21,200,1,'Crusaders',15), (22,200,2,'Waratahs',10), (23,200,3,'Lions',4), (31,300,1,'Crusaders',15), (32,300,2,'Waratahs',12), (33,300,3,'Lions',6), (41,100,4,'Crusaders',20), (42,100,5,'Waratahs',20), (43,100,6,'Lions',20) ;
Requests to show all selections, and then it’s best to choose for a specific match:
set @matchId = 2; set @winner = 'Waratahs'; set @winScore = 8;
SQL Fiddle to show selections for a specific match
Now we need to work on finding the winner of each round of the competition.
First we have additional test data containing actual points for matches in rounds 1 and 2.
create table Matches ( event_id int, winner varchar(100), score int, round int ); insert into Matches values (1,'Crusaders',10,1), (2,'Waratahs',11,1), (3,'Lions',4,1), (4,'Crusaders',20,2), (5,'Waratahs',20,2), (6,'Chiefs',20,2) ;
Now choose the best bet for all matches. Subselect (aliased as m) calculates the best_diff for each match as the minimum difference between the actual score and each guessed score. Then this subtask is connected to each selection so that only the "best" samples are returned.
Then it’s easy to get the best choices for each player for each round by simply grouping the previous query with member_nr and round:
SQL Fiddle for all the best choices and counts for all matches
The final step is to select only those players for each round who have the highest number of Best Choices. I tried modifying the above queries, but nesting becomes two confusions, so my solution was to create some logical representations so that the final query could be easily understood. The views basically embody the logic of the queries, which I explained above:
create view MatchesWithBestDiff as select m.event_id, m.winner, m.score, m.round, min(abs(m.score-p.score)) as best_diff from Matches m join Multiple_Picks p on p.event_id = m.event_id and p.pick = m.winner group by m.event_id, m.winner, m.score, m.round ; create view BestPicks as select p.*, m.round from Multiple_Picks p join MatchesWithBestDiff m on p.event_id = m.event_id and p.pick = m.winner and abs(m.score - p.score) = m.best_diff ; create view BestPickCount as select member_nr, round, count(*) as best_count from BestPicks group by member_nr, round ;
So, the query that shows the winners of each round is simple:
SQL Fiddle for Players with the Best Choice for Each Round
All this research reminded me how difficult it is to get SQL to do a lot of manipulations when records need to be selected depending on the maxima and amounts. Some of these types of queries can be much simpler with window functions (OVER and PARTITION BY clauses), but they are not available in MySQL.
When developing the above queries, I found some interesting limitations: MySQL does not allow joining subqueries in view definitions. ANSI SQL does not allow an aggregate in a subquery to refer to either a column from an internal query or a column from an external query. MySQL seems to allow this sometimes, but I couldn’t find a clear indication of when it was allowed, so I decided to program the above queries to avoid this “function”.