RESULTS : I've used three methods :
- Three sub queries, 1 join in each (mine)
- Three sub queries, no join, filtering with where (SlimsGhost)
- Triple join (Solarflare)
I've made some stats with "explain" and "profiling" which explains the work each query must do and the following results weren't surprising : stats
Relative results :
- 100%
- 79%
1715%
ORIGINAL POST
The idea is to join 4 tables, using the same PK each time and then count how many rows each join would separately gives.
The obvious answer is to do each join... separately with sub queries.
But is it possible to do it with one query? Would it be more efficient?
select "LES CIGARES DU PHARAON" as "Titre",
(select count( payalb.idPays)
from album alb
left join pays_album payalb using ( idAlb )
where alb.titreAlb = "LES CIGARES DU PHARAON") as "Pays",
(select count( peralb.idPers)
from album alb
left join pers_album peralb using ( idAlb )
where alb.titreAlb = "LES CIGARES DU PHARAON") as "Personnages",
(select count( juralb.idJur)
from album alb
left join juron_album juralb using ( idAlb )
where alb.titreAlb = "LES CIGARES DU PHARAON") as "Jurons"
;
+------------------------+------+-------------+--------+
| Titre | Pays | Personnages | Jurons |
+------------------------+------+-------------+--------+
| LES CIGARES DU PHARAON | 3 | 13 | 50 |
+------------------------+------+-------------+--------+
table album rows : 22
table pays_album rows : 45
table personnage_album rows : 100
table juron_album rows : 1704
Here is what I tried :
select alb.titreAlb as "Titre",
sum(case when alb.idAlb=payalb.idAlb then 1 else 0 end) "Pays",
sum(case when alb.idAlb=peralb.idAlb then 1 else 0 end) "Personnages",
sum(case when alb.idAlb=juralb.idAlb then 1 else 0 end) "Jurons"
from album alb
left join pays_album payalb using ( idAlb )
left join pers_album peralb using ( idAlb )
left join juron_album juralb using ( idAlb )
where alb.titreAlb = "LES CIGARES DU PHARAON"
group by alb.titreAlb
;
+------------------------+------+-------------+--------+
| Titre | Pays | Personnages | Jurons |
+------------------------+------+-------------+--------+
| LES CIGARES DU PHARAON | 1950 | 1950 | 1950 |
+------------------------+------+-------------+--------+
but it counts the total number of rows of the full joined table, ... (1950 = 3 * 13 * 50)
schema : https://github.com/LittleNooby/gbd2015-2016/blob/master/tintin_schema.png
tables content : https://github.com/LittleNooby/gbd2015-2016/blob/master/tintin_description
If you want to play to play with it :
db_init : https://github.com/LittleNooby/gbd2015-2016/blob/master/tintin_ok.mysql