Reputation: 33
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
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
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