重写SQL查询以使用Group By

时间:2016-03-06 17:24:28

标签: sql greatest-n-per-group

我正在处理Find the largest country (by area) in each continent, show the continent, the name and the area:

的练习任务

我提供了以下解决方案:

SELECT w1.continent, w1.name, w1.area
  FROM world w1
WHERE w1.area = (SELECT MAX(area)
                            FROM world w2
                          WHERE w2.continent = w1.continent)

这很有道理,也很正确。但是,在这里使用GROUP BY似乎更自然。也就是说,GROUP BY continents并挑选出具有最大面积的国家。

有人知道怎么做吗?我无法将相关的子查询转换为一个组。

2 个答案:

答案 0 :(得分:0)

要获得每个大陆的最大面积,你可以使用类似的东西。

SELECT w1.continent, MAX(w1.area)
FROM world w1
GROUP BY w1.continent

这与您的查询不完全相同,因为这不会得到相应的w1.name,因为GROUP BY需要SELECT或聚合函数中的所有GROUP BY列。由于我们不希望在名称上进行汇总或分组,因此我们可以使用JOIN或使用ROW_NUMBER这样的

<强> JOIN

SELECT w2.continent,w2.area,w2.name FROM
world w1 INNER JOIN
(
    SELECT w1.continent, MAX(w1.area) as area
    FROM world w1
    GROUP BY w1.continent
)w1
ON w1.continent = w2.continent
AND w1.area = w2.area

连接查询的问题在于,如果2个国家/地区在同一个大陆中具有相同的最大区域,那么将为该大陆重复该行

<强> ROW_NUMBER

SELECT w2.continent,w2.area,w2.name
FROM
(
SELECT w2.continent,w2.area,w2.name,ROW_NUMBER()OVER(PARTITION BY w2.continent ORDER BY w2.area DESC)as area_number 
FROM world w2
)w2
WHERE area_number = 1;

答案 1 :(得分:0)

试试这个:

;WITH CTE AS (SELECT w1.continent, w1.name, w1.area, 
                    ROW_NUMBER() OVER 
                        (PARTITION BY w1.continent order by w1.area DESC) 
                        AS rownum 
                        FROM world w1 )
SELECT continent, name, area
FROM CTE WHERE rownum=1

与其他sql语句一起使用时,请确保在WITH语句之前使用分号(;)。