views:

22

answers:

3

I have two tables - countries, tours.

countries has fields (id),(name),(order)

tours has fields (id),(id_country)...


I need to get the whole list of id and name from table countries ordered by their order, and the count of records in table tours, where tours.id_country = countries.id countries.

Ie, i need to get such list

id   name      count_of_tours
1    France    15
2    England   22
.............................

Is it possible to do in one query?

Thanks much

+2  A: 
SELECT countries.id, countries.name, COUNT(id_country) AS Count
FROM countries
LEFT JOIN tours
on tours.id_country = countries.id
GROUP BY id_country
ORDER BY countries.order
Loïc Février
GROUP BY needs to list both non-aggregated columns, but otherwise you beat me to it
Mark Baker
I didn't know that about GROUP BY, good to know ! Working only with mysql (that accept it), I had to idea that other databases wouldn't accept it. Thanks !
Loïc Février
+2  A: 
SELECT C.id,
       C.name,
       COUNT(T.id) as count_of_tours
  FROM countries C
  LEFT JOIN tours T
         ON T.id_country = C.id
 GROUP BY C.id,
          C.name
 ORDER BY C.order
Mark Baker
@Symon - when you use "aggregate functions" such as COUNT(), SUM, MAX(), etc, you need to indicate the columns that indicate a break/reset in the COUNT calculation, so SQL knows to count all T.id entries and display that count against the first C.id and C.name, then reset its internal counter to 0 and restart counting when C.id/C.name changes. The GROUP BY clause is used to identify the change point at which it needs to stop counting one set of records for one country, hold that result, reset the counter and start counting the next set of records for the next country
Mark Baker
Thanks much for detailed explanation.That is much better than in many tutorials:) But why it is needed to group them by both colomns? works with one too.
Syom
@Symon - the latest versions of MySQL seem smart enough to recognize that C.id and C.name come from the sae record in the countries table, so it's not critical to list both in the GROUP BY, but earlier versions of MySQL and other databases won't necessarily be as smart, or as forgiving... so it's a good habit to quote all non-aggregated columns in the GROUP BY... that way, it won't suddenly break the query if you decide to use Oracle or Postgres as your database, or host it on a server running an earlier version of MySQL
Mark Baker
A: 

This is real possible all you need to learn is the usage of joins. When you use join you can join the result from two tables and give the output as one.

SELECT id, name, COUNT(id_country) FROM countries LEFT JOIN tours on tours.id_country = countries.id order by countries.id;

sushil bharwani