2015-11-05 4 views
0

У меня есть вопрос для всех экспертов SQL.SQL-запрос и подзапросы

Существует таблица выглядит как:

clanname country  points 
name1  country1 100 
name2  country1 90 
name3  country1 10 
name4  country2 100 
name5  country2 80 
name6  country2 70 

Я хотел бы сделать страну рейтинге участвуют только те TOP2 результаты каждой страны. так, в этом примере, рейтинг должен быть:

country average-points 
country2 95 
country1 90 

Если есть способ, чтобы получить этот результат с только один SQL запрос с использованием подзапросов?

В действительности у меня есть более 200 стран .. и тысячи результатов для каждой страны. Но я бы хотел отфильтровать только 30 лучших результатов каждой страны.

Сейчас мне удалось получить среднее одной страны, используя этот запрос:

SELECT 
     location, AVG(warswon) 
    FROM 
     (SELECT 
      `name`, `location`, `warswon` 
     FROM 
      `clans` 
     WHERE 
      location = 'China' 
     ORDER BY 
      `clans`.`warswon` DESC 
     LIMIT 30) AS top30ofcountry 

, но как я могу получить средние результаты каждой страны в одном запросе?

Возможно ли это?

+0

GROUP BY [имя_поль] –

+0

добавить в конце 'GROUP BY location' – Mihai

+0

Зачем вам нужен подзапрос для этого? –

ответ

2

Это n проблем на группу. Это тривиально во многих БД, используя row_number. В MySQL вы можете сделать это с пользовательскими переменными

SELECT 
    country , 
    avg(points) 
FROM 
(
    SELECT 
     @num := if(@group = `country`, @num + 1, 1) as row_number, 
     @group := `country` as dummy, 
     clanName, 
     country, 
     points 
    FROM 
     clans 
     JOIN (SELECT @group := NULL, @num := 0) as z 
    order by 
     country, points desc) as x 
WHERE x.row_number <=2 
GROUP BY 
    country 
+0

ok conrad .. У меня такое ощущение, что это близко к запросу, который мне нужен. Я использую mysql, и все предложения GROUP BY из прежнего сообщения не помогают. –

0

Спасибо за помощь Конрад. Мне удалось получить полученный результат, лишь слегка изменив предложенный вами код. Вот окончательный рабочий запрос для тех, у кого есть подобные вопросы:

SELECT 
location, 
avg(warswon) 
FROM 
(
SELECT 
@num := if(@group = `location`, @num + 1, 1) as row_number, 
@group := `location` as dummy, 
name, 
location, 
warswon 
FROM 
clans 
JOIN (SELECT @group := NULL, @num := 0) as z 
order by 
location, warswon desc 
) as x 
WHERE x.row_number <= 30 
GROUP BY `location` 
ORDER BY avg(warswon) DESC