2011-04-13 5 views
1

j'ai créé un exemple simple de test:mysql jointure gauche plusieurs tables avec un à-plusieurs

CREATE TABLE `t1` (
    `id` int NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) 

CREATE TABLE `t2` (
    `id2` int NOT NULL AUTO_INCREMENT, 
    `id1` int, 
    PRIMARY KEY (`id2`) 
) 

CREATE TABLE `t3` (
    `id3` int NOT NULL AUTO_INCREMENT, 
    `id1` int, 
    PRIMARY KEY (`id3`) 
) 

insert into t1 (id) values (1); 

insert into t2 (id1) values (1),(1); 

insert into t3 (id1) values (1),(1),(1),(1); 

Je dois sélectionner toutes les données Distinct de t1 jointure gauche t2 et les données Distinct de t1 jointure gauche t3, renvoyant un total de 6 lignes, 1 x (2 [de t2] + 4 [de t3]) = 6, mais étant donné la nature de cette jointure, j'obtiens 8 lignes, 1 [de t1] x 2 [de t2] x 4 [de t3] = 8.

select * from t1 left join t2 on (t1.id = t2.id1); 
2 rows in set (0.00 sec) 

select * from t1 left join t3 on (t1.id = t3.id1); 
4 rows in set (0.00 sec) 

select * from t1 left join t2 on (t1.id = t2.id1) left join t3 on (t1.id = t3.id1); 
8 rows in set (0.00 sec) 

select * from t1 left join t2 on (t1.id = t2.id1) union select * from t1 left join t3 on (t1.id = t3.id1); 
4 rows in set (0.00 sec) 

Quelle requête dois-je utiliser pour obtenir seulement les 6 lignes dont j'ai besoin, est-il sans que posible ou je les sous-requêtes besoin (il sera plus complicatet i n la grande question où j'en ai besoin)? J'ai besoin de ceci pour une grande requête où j'obtiens déjà des données de 8 tables, mais je dois obtenir des données de 2 plus pour obtenir toutes les données dont j'ai besoin en une seule requête, mais en rejoignant la 9ème table, les données retournées get est dupliqué (la 9ème table dans ce cas de test simple sera t3, et la 8ème sera t2).

J'espère que quelqu'un pourrait me montrer le bon chemin à suivre.
Merci.

MISE À JOUR RESOLU: Je ne vraiment sais pas comment faire ce cas de test dans une sélection, mais dans ma BigQuery je l'ai résolu de cette façon: beacause je group_concat et le groupe par, je l'ai fait par spliting une valeur multipe group_concat (dISTINCT ...) et concat tous comme cette

// instead of this 
... group_concat(DISTINCT concat(val1, val2, val3)) ... 
// I did this 
concat(group_concat(DISTINCT val1,val2), group_concat(DISTINCT val1,val3)) ... 

de sorte que le distincte sur les petits groupes de valeur éviter tous ces doublons.

+0

Comment pouvez-vous avoir une clé primaire avec une valeur par défaut? –

+0

@nick rulez: Je n'ai pas remarqué cela, j'ai changé la colonne en t2, t3 d'id, en id2, id3 et mysql mettre la valeur par défaut, mis à jour la question. ...: P –

Répondre

0

Je ne sais pas si vous cherchez cette solution

select * from t1 left join t2 on (t1.id = t2.id1); 
union all 
select * from t1 left join t3 on (t1.id = t3.id1); 
+0

J'ai commencé à faire la grosse requête avec des sous-requêtes, cela semble la seule possibilité. Je vais laisser la question ouverte pendant quelques jours pour voir si quelqu'un nous enseignera une autre façon de le faire. –

+0

Cela va jeter un _Error Code: 1064_ en raison d'une mauvaise utilisation de UNION ALL. –

0

Je pense qu'il ya une petite erreur dans rulez requête de @ Nick ». S'il est écrit comme ceci, il retourne vraiment 6 lignes:

(SELECT * FROM t1 LEFT JOIN t2 ON (t1.id = t2.id1)) 
    UNION ALL 
(SELECT * FROM t1 LEFT JOIN t3 ON (t1.id = t3.id1))