I need to get a listing of top 2 Names in every Country (from Accounts & Country Table). I have searched a lot and also have found some valid answers, but cannot get the correct results.
Please see my SQL Fiddle here:
http://sqlfiddle.com/#!9/cd1296/5
CREATE TABLE IF NOT EXISTS `country` (
`id` int(6) unsigned NOT NULL,
`iso` varchar(3) NOT NULL,
`country_name` varchar(24) NOT NULL,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
INSERT INTO `country` (`id`, `iso`,`country_name`) VALUES
('1', 'DEU','Germany'),
('2', 'USA','United States'),
('3', 'CAN','Canada'),
('4', 'JPN','Japan');
CREATE TABLE IF NOT EXISTS `accounts` (
id int(6) unsigned NOT NULL,
name varchar(50) NOT NULL,
iso3 varchar(3) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `accounts` (`id`,`name`, `iso3`) VALUES
('1', 'Hans', 'DEU'),
('2', 'Willi', 'DEU'),
('3', 'Peter', 'DEU'),
('4', 'Susanne', 'DEU'),
('5', 'John', 'USA'),
('6', 'Jane', 'USA'),
('7', 'Peter', 'USA'),
('8', 'Paul', 'USA'),
('9', 'Mary', 'USA'),
('10', 'Gerard', 'CAN'),
('11', 'Mirelle', 'CAN'),
('12', 'Hiko', 'JPN'),
('13', 'Miko', 'JPN'),
('14', 'Susanne', 'DEU'),
('15', 'Peter', 'DEU'),
('16', 'John', 'USA'),
('17', 'Paul', 'USA'),
('18', 'Susanne', 'DEU'),
('19', 'Bob', 'DEU'),
('20', 'John', 'USA'),
('21', 'Paul', 'USA'),
('33', 'Gerard', 'CAN'),
('22', 'Maribelle', 'CAN'),
('23', 'Gerd', 'CAN'),
('24', 'Mira', 'CAN'),
('25', 'Huko', 'JPN'),
('26', 'Hako', 'JPN'),
('27', 'Hiko', 'JPN'),
('28', 'Jon', 'USA'),
('29', 'Jim', 'USA'),
('30', 'John', 'USA'),
('31', 'JJ', 'USA'),
('32', 'Bob', 'USA'),
('34', 'Bob', 'USA'),
('35', 'Miko', 'JPN'),
('36', 'Miko', 'JPN');
Using this Statement brings the list in correct order, but does not stop after the second result:
SELECT country_name, iso, name, COUNT(name) AS name_count
FROM accounts
JOIN country ON country.iso = accounts.iso3
GROUP BY country.iso, name
ORDER BY country.iso ASC, name_count DESC;
As suggested in other questions/answers the solution could be use "MySQL session variables" (based on https://www.databasejournal.com/features/mysql/selecting-the-top-n-results-by-group-in-mysql.html).
My Problem: The country_rank is not populating correctly and so not giving corrent results. What I am doing wrong?
SET @current_country = "";
SET @country_rank = 0;
SELECT country_name, name, name_count, rank
FROM
(
SELECT country_name, iso, name, COUNT(name) AS name_count,
@country_rank := IF( @current_country = iso,
@country_rank + 1,
1
) AS rank,
@current_country := iso
FROM accounts
JOIN country ON country.iso = accounts.iso3
GROUP BY country.iso, name
ORDER BY country.iso ASC, name_count DESC
) AS ranked
WHERE rank<=2;