2009-10-15 5 views
0

J'ai un scénario où je dois faire une jointure entre trois tables.Est-il possible de restreindre les résultats d'une jointure externe?

 
table #1 is a list of users 
table #2 contains users who have trait A 
table #3 contains users who have trait B 

Si je veux trouver tous les utilisateurs qui ont trait A ou B trait (dans un sql simple,) Je pense que je suis coincé.

Si je fais une jointure régulière, les personnes qui n'ont pas de trait A n'apparaîtront pas dans le jeu de résultats pour voir si elles ont le trait B (et vice versa). Mais si je fais une jointure externe de la table 1 aux tables 2 et 3, j'obtiens toutes les lignes du tableau 1 indépendamment du reste de ma clause where spécifiant une exigence par rapport aux tables 2 ou 3.

Avant de monter avec plusieurs sqls et tables temporaires et autres joyeusetés, ce programme est beaucoup plus complexe, c'est juste le cas simple. Il crée dynamiquement le sql basé sur beaucoup de facteurs externes, donc j'essaye de le faire fonctionner dans un sql. Je m'attends à ce qu'il existe des combinaisons de dans ou existe qui fonctionnera, mais j'espérais quelque chose de simple. Mais fondamentalement, la jointure externe donnera toujours tous les résultats de la table 1, oui?

Répondre

3
SELECT * 
    FROM table1 
LEFT OUTER 
    JOIN table2 
    ON ... 
LEFT OUTER 
    JOIN table3 
    ON ... 
WHERE NOT (table2.pk IS NULL AND table3.pk IS NULL) 

ou si vous voulez être sournoise:

WHERE COALESCE(table2.pk, table3.pk) IS NOT NULL 

mais pour vous cas, je suggère simplement:

SELECT * 
    FROM table1 
WHERE table1.pk IN (SELECT fk FROM table2) 
    OR table1.pk IN (SELECT fk FROM table3) 

ou peut-être plus efficace:

SELECT * 
    FROM table1 
WHERE table1.pk IN (SELECT fk FROM table2 UNION (SELECT fk FROM table3) 
1

Je pense que vous pourriez faire une union ici.

1

Je suggère:

SELECT columnList FROM Table1 WHERE UserID IN (SELECT UserID FROM Table2) 
UNION 
SELECT columnList FROM Table1 WHERE UserID IN (SELECT UserID FROM Table3) 
2

Si vous voulez vraiment que la liste des utilisateurs qui ont un trait ou l'autre, puis:

SELECT userid FROM users 
    WHERE userid IN (SELECT userid FROM trait_a UNION SELECT userid FROM trait_b) 

En ce qui concerne jointure ouverte spécifiquement, la réponse de longneck ressemble à ce que J'étais en train d'écrire.

1

Quelque chose comme ceci fonctionnerait? Gardez à l'esprit en fonction de la taille des tables gauche jointures externes peuvent être très coûteux en termes de performances.

Select * 
from table1 
where userid in (Select t.userid 
From table1 t 
left outer join table2 t2 on t1.userid=t2.userid and t2.AttributeA is not null 
left outer join table3 t3 on t1.userid=t3.userid and t3.AttributeB is not null 
group by t.userid) 
1

Si vous voulez simplement les IDs des utilisateurs puis

SELECT UserId From Table2 
UNION 
SELECT UserId From Table3 

est tout à fait suffisant.

Si vous voulez des infos de plus sur ces utilisateurs Tableau1, vous pouvez rejoindre le SQL supérieur au Tableau 1:

SELECT <list of columns from Table1> 
FROM Table1 Join (
    SELECT UserId From Table2 
    UNION 
    SELECT UserId From Table3) User on Table1.UserID = Users.UserID 
Questions connexes