views:

65

answers:

1

I have two tables: attractions and cities. Attractions contains a column called city, which is a reference to the id in the cities table. I want to form a MySQL statement that will show me which cities have the most attractions.

I know I can do:

SELECT COUNT(*) as `number` 
 FROM `attractions` 
WHERE `city` = XX 

...to get a count of how many attractions are in one city, but is there one statement that can count all of the attractions in every city, and return the results in descending order by number of attractions?

+2  A: 
SELECT City.Name, COUNT(Attractions.City) as AttractionCount
FROM City
LEFT OUTER JOIN Attractions ON City.City = Attractions.City
GROUP BY City.Name
ORDER BY COUNT(Attractions.City) DESC
bobs
Perhaps you should replace City.City with City.id? Also, group by City.id rather than City.Name, since there may be multiple cities with the same name (in different provinces or states).
Mark Eirich
yes, that's a good option. However, the question indicated that the column in Attractions is called City.
bobs
Worked perfectly! Thank you! And it does make more sense to group by id rather than name.
Jarred
Possibly `COUNT(Attractions.City)` rather than `COUNT(*)`, as there may be 0 attractions in a city (based on the left outer join)?
Mark Bannister
@Mark, you may be right, it's important to distinguish between COUNT(*) and COUNT(<column_name>). But I'm not sure it matters in this case. COUNT(*) will return number of rows returned, including a 0 if there are no attractions associated with a City.
bobs
@bobs: unless mysql handles `count(*)` differently to every other database I've used, it will return `count(*)` as 1 where there are 0 attractions. Try this, in SQLServer: `select c.city, count(*), count(a.city) from (select 'Paris' city union all select 'Marseille' city) c left outer join (select 'Paris' city) a on a.city = c.city group by c.city`
Mark Bannister
@Mark: You are correct. My comment on that is wrong. I will change my answer for posterity. Rats :)
bobs