Is there a simple way to LIMIT the GROUP BY results to the top 2. The following query returns all the results. Using \'LIMIT 2\' reduces the overall list to the top 2 entr
This is still possible via a single query, but it's a bit long, and there are some caveats, which I'll explain after the query. Though, they're not flaws in the query so much as some ambiguity in what "top two" means.
Here's the query:
SELECT ratings.* FROM
(SELECT rating_name,
id_markets,
sum(rating_good) 'good',
sum(rating_neutral)'neutral',
sum(rating_bad) 'bad'
FROM zzratings
WHERE rating_year=year(curdate()) AND rating_week = week(curdate(),1)
GROUP BY rating_name,id_markets) AS ratings
LEFT JOIN
(SELECT rating_name,
id_markets,
sum(rating_good) 'good',
sum(rating_neutral)'neutral',
sum(rating_bad) 'bad'
FROM zzratings
WHERE rating_year=year(curdate()) AND rating_week= week(curdate(),1)
GROUP BY rating_name,id_markets) AS ratings2
ON ratings2.good <= ratings.good AND
ratings2.id_markets <> ratings.id_markets AND
ratings2.rating_name = ratings.rating_name
LEFT JOIN
(SELECT rating_name,
id_markets,
sum(rating_good) 'good',
sum(rating_neutral)'neutral',
sum(rating_bad) 'bad'
FROM zzratings
WHERE rating_year=year(curdate()) AND rating_week= week(curdate(),1)
GROUP BY rating_name,id_markets) AS ratings3
ON ratings3.good >= ratings2.good AND
ratings3.id_markets <> ratings.id_markets AND
ratings3.id_markets <> ratings2.id_markets AND
ratings3.rating_name = ratings.rating_name
WHERE (ratings2.good IS NULL OR ratings3.good IS NULL) AND
ratings.good IS NOT NULL
ORDER BY ratings.rating_name, ratings.good DESC
The caveat is that if there is more than one id_market with the same "good" count for the same rating_name, then you will get more than two records. For example, if there are three ireland id_markets with a "good" count of 3, the highest, then how can you display the top two? You can't. So the query will show all three.
Also, if there were one count of "3", the highest, and two counts of "2", you couldn't show the top two, since you have a tie for second place, so the query shows all three.
The query will be simpler if you create a temporary table with the aggregate result set first, then work from that.
CREATE TEMPORARY TABLE temp_table
SELECT rating_name,
id_markets,
sum(rating_good) 'good',
sum(rating_neutral)'neutral',
sum(rating_bad) 'bad'
FROM zzratings
WHERE rating_year=year(curdate()) AND rating_week= week(curdate(),1;
SELECT ratings.*
FROM temp_table ratings
LEFT JOIN temp_table ratings2
ON ratings2.good <= ratings.good AND
ratings2.id_markets <> ratings.id_markets AND
ratings2.rating_name = ratings.rating_name
LEFT JOIN temp_table ratings3
ON ratings3.good >= ratings2.good AND
ratings3.id_markets <> ratings.id_markets AND
ratings3.id_markets <> ratings2.id_markets AND
ratings3.rating_name = ratings.rating_name
WHERE (ratings2.good IS NULL OR ratings3.good IS NULL) AND
ratings.good IS NOT NULL
ORDER BY ratings.rating_name, ratings.good DESC;