Reputation: 2464
This is really complicated, then I will say an example in order to make it easier.
Imagine that we have 4 tables: garages, cars, securities, places.
garages
is where you can find the cars
, securities
is the security that is keeping that car safe inside of a garage, and places
is where you can find garages similar to that one. Then we have a table like that.
garages table:
-----------------------------------
|garage_id|garage_name|garage_size|
-----------------------------------
| 1| Garage 1| 200|
-----------------------------------
| 2| Garage 2| 400|
-----------------------------------
cars table:
---------------------------
|car_id|car_name|garage_id|
---------------------------
| 1| Car 1| 1|
---------------------------
| 2| Car 2| 1|
---------------------------
| 3| Car 3| 2|
---------------------------
securities table:
----------------------------------
|security_id|security_name|car_id|
----------------------------------
| 1| Security 1| 1|
----------------------------------
| 2| Security 2| 1|
----------------------------------
| 3| Security 3| 2|
----------------------------------
| 4| Security 4| 3|
----------------------------------
places table:
-------------------------------
|place_id|place_name|garage_id|
-------------------------------
| 1| place 1| 1|
-------------------------------
| 2| place 2| 1|
-------------------------------
| 3| place 3| 1|
-------------------------------
| 4| place 4| 2|
-------------------------------
| 5| place 5| 2|
-------------------------------
What I want is to list the garages and join the three tables that is cars, securities and places like this:
Garage 1 has 2 cars with 3 securities and has 3 more garages similar
Garage 2 has 1 cars with 1 securities and has 2 more garages similar
Now you might ask, why Garage 1
has 3 securities? Because the Garage 1
has Car 1
and Car 2
and Car 1
has two securities Security 1
and Security 2
and Car 2
has 1 that is Security 3
.
The problem here is: How to join the tables and count in one single query and return the result just like you can see above?
Upvotes: 0
Views: 76
Reputation: 94884
Simply join all tables, group by garage and count distinct matches:
select
g.garage_name,
count(distinct c.car_id) as count_cars,
count(distinct s.security_id) as count_securities,
count(distinct p.place_id) as count_places
from garages g
left join cars c on c.garage_id = g.garage_id
left join securities s on s.car_id = c.car_id
left join places p on p.garage_id = g.garage_id
group by g.garage_name
order by g.garage_name;
As to the desired output strings, concatenate your results:
g.garage_name || ' has ' || count(distinct c.car_id) || ' cars with ' || ...
Upvotes: 2
Reputation: 72186
This query should do the job:
SELECT g.garage_id, g.garage_name, COUNT(c.car_id) AS nb_cars,
COUNT(s.security_id) AS nb_securities, COUNT(p.place_id) AS nb_places
FROM garages g
LEFT JOIN cars c ON g.garage_id = c.garage_id
LEFT JOIN securities c.car_id = s.car_id
LEFT JOIN places.p ON g.garage_id = p.garage_id
GROUP BY g.garage_id
You will get the list of all garages, including those that do not have cars or places around. If you want to filter out the garages without cars then use INNER JOIN cars ...
. To filter out the garages without places, use INNER JOIN places ...
.
Upvotes: 1
Reputation: 582
SELECT
gb.garage_name,
(
SELECT COUNT(*) FROM cars_table ct WHERE ct.garage_id = db.garage_id
) as car_count,
(
SELECT COUNT(*) FROM security_table st JOIN cars_table ct ON ct.car_id = st.car_id WHERE ct.garage_id = db.garage_id
) as security_count,
FROM
garages_table gb
ORDER BY gb.garage_id
This is untested, but it's an idea.
Upvotes: 1