2010-11-24 5 views
0

Mon SQL-fu est trop faible pour cela, et je ne suis même pas sûr que ce soit possible dans un seul appel SQL.Est-il possible de sélectionner plusieurs comptes conditionnels sur trois tables dans une même requête SQL?

Étant donné que j'ai les tableaux suivants:

PARTNER 
+----+--------+ 
| id | name | 
+----+--------+ 
| 1 | bloggs | 
| 2 | jones | 

PARTNER MANAGER 
+----+--------------+------+ 
| id | partner_id | name | 
+----+--------------+------+ 
| 1 | 1   | fred | 
| 2 | 2   | dave | 

COMPANY 
+----+--------------------+--------+----------+ 
| id | partner_manager_id | name | active | 
+----+--------------------+--------+----------+ 
| 1 | 1     | comp1 | true  | 
| 2 | 1     | comp2 | false | 
| 3 | 2     | comp3 | true  | 
| 4 | 2     | comp4 | true  | 
| 5 | 2     | comp5 | true  | 
| 6 | 2     | comp6 | true  | 

Je voudrais génèrerait les éléments suivants dans un seul appel SQL:

+--------------+--------------------+----------------------+ 
| partner_name | n_active_companies | n_inactive_companies | 
+--------------+--------------------+----------------------+ 
| bloggs  | 1     | 1     | 
| jones  | 4     | 0     | 

je peux rejoindre les trois tables en utilisant deux LEFT JOINs mais comment Je peux agréger les comptes (avec ou sans la clause WHERE) m'échappe. Est-ce que j'aboie le mauvais arbre, pour ainsi dire?

+0

je préfère utiliser une vue SQL si vous voulez partir d'un seul statment – Sudantha

Répondre

2

Cela vous obtient la plupart du chemin:

SELECT 
    partner_manager_id, 
    SUM(CASE WHEN active THEN 1 ELSE 0 END) AS n_active_companies, 
    SUM(CASE WHEN active THEN 0 ELSE 1 END) AS n_inactive_companies 
FROM COMPANY 
GROUP BY partner_manager_id 

Le reste de votre question demande essentiellement comment joindre ce résultat aux tables restantes. Comme vous le faites remarquer, pour ce faire, utilisez JOINs.

SELECT 
    PARTNER.name, 
    T1.n_active_companies, 
    T1.n_inactive_companies 
FROM 
PARTNER 
LEFT JOIN PARTNER_MANAGER ON partner_id = PARTNER.id 
LEFT JOIN 
(
    SELECT 
     partner_manager_id, 
     SUM(CASE WHEN active THEN 1 ELSE 0 END) AS n_active_companies, 
     SUM(CASE WHEN active THEN 0 ELSE 1 END) AS n_inactive_companies 
    FROM COMPANY 
    GROUP BY partner_manager_id 
) T1 
ON T1.partner_manager_id = PARTNER_MANAGER.id 
+0

C'est le cœur de la réponse que j'écrivais ... juste besoin les jointures pour traduire le partner_manager_id au partenaire. nom – chezy525

+0

@ chezy525: Ajouté que maintenant. –

0
select p.name "Partner Name" 
, c1.cnt "n_active_companies" 
, c2.cnt "n_inactive_companies" 
from partner p 
, (select partner_manager_id id, count(partner_manager_id) cnt from company where active = 'true' group by partner_manager_id) c1 
, (select partner_manager_id id, count(partner_manager_id) cnt from company where active = 'false' group by partner_manager_id) c2 
where c1.id = p.id 
and c2.id = p.id 
0
select p.name as 'partner_name', 
     sum(case when active then 1 else 0) as 'n_active_companies', 
     sum(case when active then 0 else 1) as 'n_inactive_companies' 
from COMPANY c 
    join PARTNER_MANAGER pm on c.partner_manager_id = pm.id 
    join PARTNER p on pm.partner_id = p.id 
group by p.name 
Questions connexes