Ryan Haslag
Ryan Haslag

Reputation: 33

SQL return based on Aggregate Function

I have this query that works, but it returns information for all cities and I only want to return based on the max population in the city for each row for one country but aggregate functions can't be used in the where clause. How can I limit my results to one per country?

SELECT lab6.country.name, max(lab6.city.population) AS largest_pop 
  FROM lab6.country, lab6.city 
 WHERE lab6.country.country_code = lab6.city.country_code 
 GROUP BY lab6.country.name, lab6.city.name"

Upvotes: 1

Views: 230

Answers (2)

Wilduck
Wilduck

Reputation: 14096

Maybe I'm misunderstanding but do you just want to return the largest city in each country?

If so, you simply can group by country, instead of by country and city. You'll need to include the attribute that identifies a country, and the name of that country in your GROUP BY statement. Your query will end up looking like:

SELECT lab6.country.name AS cName, max(lab6.city.population) AS largest_pop 
FROM lab6.country, lab6.city 
WHERE lab6.country.country_code = lab6.city.country_code 
GROUP BY lab6.country.country_code, lab6.country.name

If you want to also include the name of the largest city, you'll first need to decide what to do if there are multiple largest cities (countries where there are two or more cities with the same, largest, population). I'm going to assume you're okay with including them all. In that case, you can simply do a sub-query in your FROM clause, joined on cities with the same population:

SELECT lc.cName, lab6.city.name, lc.largest_pop
FROM (
      SELECT lab6.country.country_code AS cCode
             lab6.country.name AS cName, 
             max(lab6.city.population) AS largest_pop 
      FROM lab6.country, lab6.city 
      WHERE lab6.country.country_code = lab6.city.country_code 
      GROUP BY lab6.country.country_code, lab6.country.name
     ) AS lc
     JOIN lab6.city ON lc.cCode = lab6.city.country_code 
WHERE lab6.city.population = lc.largest_pop

Upvotes: 0

John Woo
John Woo

Reputation: 263693

PostgreSQL supports window functions that you can take advantage with.

SELECT  countryName, cityName, largest_pop
FROM
        (
            SELECT  a.name countryName, 
                    b.name cityName, 
                    b.population AS largest_pop,
                    DENSE_RANK() OVER (PARTITION BY a.name 
                                        ORDER BY b.population DESC) rn
            FROM    lab6.country a, lab6.city b 
            WHERE   a.country_code = b.country_code 
        ) x
WHERE   rn = 1

Upvotes: 1

Related Questions