2009-01-29 6 views
0

Vous avez une table avec laquelle vous souhaitez compter le nombre d'éléments dans deux tables différentes. Dans cet exemple j'ai utilisé des bâtiments, hommes et femmesEst-il possible de générer des rapports sur 2 tables sans utiliser de sous-requête?

DROP TABLE IF EXISTS building; 
DROP TABLE IF EXISTS men; 
DROP TABLE IF EXISTS women; 
CREATE TABLE building(name VARCHAR(255)); 
CREATE TABLE men(building VARCHAR(255), name VARCHAR(255)); 
CREATE TABLE women(building VARCHAR(255), name VARCHAR(255)); 
INSERT INTO building VALUES('building1'); 
INSERT INTO building VALUES('building2'); 
INSERT INTO building VALUES('building3'); 
INSERT INTO men VALUES('building1', 'andy'); 
INSERT INTO men VALUES('building1', 'barry'); 
INSERT INTO men VALUES('building2', 'calvin'); 
INSERT INTO men VALUES(null, 'dwain'); 
INSERT INTO women VALUES('building1', 'alice'); 
INSERT INTO women VALUES('building1', 'betty'); 
INSERT INTO women VALUES(null, 'casandra'); 

select 
    r1.building_name, 
    r1.men, 
    GROUP_CONCAT(women.name) as women, 
    COUNT(women.name) + r1.men_count as count 
from 
    (select 
     building.name as building_name, 
     GROUP_CONCAT(men.name) as men, 
     COUNT(men.name) as men_count 
    from 
     building 
    left join 
     men on building.name=men.building 
    GROUP BY building.name) as r1 
left join 
    women on r1.building_name=women.building 
GROUP BY r1.building_name; 

Peut-il y avoir un autre moyen? Le problème avec l'approche ci-dessus est que les colonnes des deux tables de la sous-requête sont masquées et doivent être redéclarées dans la requête externe. Le faire en deux opérations séparées crée une asymétrie là où il n'y en a pas. Nous aurions aussi pu rejoindre les femmes d'abord, puis les hommes.

Répondre

1

Dans SQL Server, je voudrais juste joindre deux sous-requêtes avec deux gauche rejoint - si la symétrie est ce que vous cherchez:

SELECT * 
FROM building 
LEFT JOIN (SELECT building, etc. FROM men GROUP BY etc.) AS men_summary 
    ON building.name = men_summary.building_name 
LEFT JOIN (SELECT building, etc. FROM women GROUP BY etc.) AS women_summary 
    ON building.name = women_summary.building_name 

J'ai tendance à utiliser des expressions de table commune a déclaré d'abord au lieu de les sous-requêtes - il est loin plus lisible (mais pas ANSI - mais pas non plus GROUP_CONCAT).

+0

Thx - peut-être ce que je veux, pas encore décidé. Oh GROUP_CONCAT était juste une fonction d'agrégation pratique pour l'exemple. –

1

Utilisez Union pour combiner les données des hommes/femmes tables

select building, [name] as menname, null as womenname from men 
union 
select building, null as menname, [name] as womenname from women 

vous avez maintenant une « table » unique addmitedly dans une sous-requête contre laquelle vous pouvez rejoindre, compter ou autre chose.

BTW Je peux voir pourquoi Cas [s] andra est dehors dans le froid comme personne ne la croit, mais qu'en est-il de dwain, est-il également maudit par les dieux?

+0

euh, peut-être ... je suppose que ce serait le nain rouge s'il doit y avoir une référence. –