0

I have a mysql select query like this:

select r.restaurant_id, r.restaurant_name, r.city_id, c.name
from restaurants r
inner join cities c on c.id = r.city_id;  

This is the result of above query:

+---------------+----------------------+---------+-------------+
| restaurant_id | restaurant_name      | city_id | name        |
+---------------+----------------------+---------+-------------+
|             7 | Somasiri Bake House  |       5 | Mumbai      |
|             8 | Indian    Bake House |       7 | Chennai     |
|             9 | KFC Rest             |       5 | Mumbai      |    
|            10 | Indian t             |       5 | Mumbai      |
+---------------+----------------------+---------+-------------+

Now I want to display all the available cities with the number of restaurants existing to one city.

Eg: Mumbai (3), Chennai(1) and so on

I tried it like below with mysql COUN(), but it doesn't work for me.

SELECT c.name, count(r.city_id) AS count
FROM cities c
INNER JOIN restaurants r ON c.id = r.city_id;

Can anybody tell me what is the wrong with this?

Hope somebody may help me out. Thank you.

2

3 Answers 3

1
SELECT c.name, COALESCE(count(r.city_id), 0) AS count
FROM cities c
LEFT JOIN restaurants r ON c.id = r.city_id
GROUP BY c.id
Sign up to request clarification or add additional context in comments.

2 Comments

Can not get all available cities.
Yes.. This is what I needed. Thank you very much
1

Use a simple group by if you don't want restaurant data:

select c.name, count(r.city_id) as available
from cities c
left join restaurants r on c.id = r.city_id
group by r.city_id

See SQLFiddle.


Or, if you want restaurant data too, select from cities first, then left join to other tables so cities without restaurants still get returned. Add a left join to a subquery that calculates each city's frequency:

select
  r.restaurant_id,
  r.restaurant_name,
  c.id,
  c.name,
  coalesce(available, 0) available
from cities c
left join restaurants r on c.id = r.city_id
left join (select city_id, count(*) available from restaurants group by 1) a
  on a.city_id = r.city_id

See SQLFiddle.

5 Comments

Bohemian, your query returned all the available restaurants with city counts. But I need to display all the cities and if there are restaurant for these cities then I need to display count number along with city.
@user3733831 do you want a zero in the "available" column for each city that has no restaurants in it, and to display nulls for the restaurant details in that case?
Yes it may have null values for cities. Reason is there are no restaurants for every cities and I don't need to have duplicate of cities in the query. Thank you.
@user3733831 try the new version (sqlfiddle link has been updated too)
Yes dear.. your query is working. But city names are duplicating. Actually I need like city1 (3), city2 (5), city3 (8), city4 (11), city5
1

That's called a grouping or aggregate query, you need to tell it how to group your elements.

Just add

GROUP BY r.restaurant_id, r.restaurant_name, r.city_id, c.name

at the end, before your final semi-colon.

5 Comments

I'd encourage the correct use of GROUP BY (not MySQL's incorrect behavior) by adding all the SELECT columns to the group: GROUP BY r.restaurant_id, r.restaurant_name, r.city_id, c.name Using GROUP BY r.city_id alone would be an error in almost any other database.
yes its working... but it doesnt select all the cities
@MichaelBerkowski . . . I agree with you in general. However, this particular example is not incorrect behavior according to ANSI, because of the notion of functional dependence. I think Postgres, which may be the only database that implements this functionality correctly, does an adequate job of explaining the notion (postgresql.org/docs/9.4/static/sql-select.html).
Can we select all available cities even if there is no any restaurant
I agree with @MichaelBerkowski, grouping by all un-aggregated columns is ideal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.