2015-11-05 141 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 

我想作一个国家的排名只涉及每个国家的前2项结果。所以,在这个例子中,排名应该是:

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

这是每组问题。这在许多数据库中使用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

好康拉德..我有这种感觉接近我需要的查询。我使用mysql和以前的帖子的所有GROUP BY提案都没有帮助。 –

0

感谢您的帮助康拉德。 我设法得到reqested结果只是稍微改变你提出的代码。 这里是为那些谁也有类似的问题,最终的工作查询:

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