2010-03-22 9 views
5

J'ai un scénario dans lequel je souhaite activer deux tables différentes dans une jointure externe. Il va quelque chose comme ceci: -Utilisation d'instructions CASE dans LEFT OUTER JOIN dans SQL

  select mytable.id, 
       yourtable.id 
      from mytable 
left outer join (case 
        when mytable.id = 2 then table2 
         yourtable on table1.id = table2.id 
        else 
         table3 yourtable on table1.id = table3.id 
       end) 

... mais cela ne fonctionne pas. Aucune suggestion?

+2

Il pourrait être utile de réexaminer la conception de votre base de données. Si à la fois table2 et table3 ont des schémas identiques ou similaires, pourquoi sont-ils des tables différentes? –

+0

Il vaut également la peine de réexaminer votre exemple. Il semble y avoir alias/nom de table mélangé. – jva

+0

Il suffit de joindre aux deux tables et de déplacer la partie CASE vers la liste des colonnes – user38123

Répondre

4

Utilisation (Oracle 9i +):

SELECT mt.id, 
      COALESCE(yt1.id, yt2.id) 
    FROM MYTABLE mt 
LEFT JOIN YOURTABLE yt1 ON yt1.id = mt.id 
         AND yt.id = 2 
LEFT JOIN YOURTABLE yt2 ON yt2.id = mt.id 
+0

Pour les lignes où mt.id est 2, mais il y a plusieurs correspondances dans yt2 pour cet id, cela pourrait générer des doublons. –

+0

@Gary: C'est vrai, j'y ai pensé lors de la publication, mais j'ai décidé de publier une requête correspondant à l'OP verbatim. –

+0

Merci. Cela a bien fonctionné et non, il n'y a pas de valeurs en double, donc ça a aussi bien marché. –

1

Cette requête rejoint les enregistrements de la table EMP soit la table DEPT ou la table SPECIAL_OPS, en fonction de la valeur de EMP.DEPTNO ...

SQL> select e.ename 
    2   , e.job 
    3   , e.deptno 
    4   , coalesce(d.dname, s.dname) as dname 
    5 from emp e 
    6  left outer join dept d 
    7    on (e.deptno = 30 
    8     and e.deptno = d.deptno) 
    9  left outer join special_ops s 
10    on (e.deptno != 30 
11     and e.deptno = s.deptno) 
12 where e.deptno in (30,50) 
13 order by e.deptno, e.empno 
14/

ENAME  JOB   DEPTNO DNAME 
---------- --------- ---------- -------------- 
VAN WIJK SALESMAN   30 SALES 
PADFIELD SALESMAN   30 SALES 
BILLINGTON SALESMAN   30 SALES 
SPENCER MANAGER   30 SALES 
CAVE  SALESMAN   30 SALES 
HALL  CLERK    30 SALES 
VERREYNNE PLUMBER   50 SKUNKWORKS 
FEUERSTEIN PLUMBER   50 SKUNKWORKS 

8 rows selected. 

SQL> 

J'ai inclus le filtre sur EMP.DEPTNO dans les clauses ON. Cela peut être inutile si les données dans les tables sont exclusives (c'est-à-dire que DEPTNO = 30 ne peut se joindre qu'à DEPT et DEPTNO = 50 ne peut que se joindre à SPECIAL_OPS). Cependant, si l'identifiant peut apparaître dans les deux tables, il est également nécessaire d'être explicite. En outre, rendre notre intention claire est toujours une bonne pratique. En dehors de toute autre chose, nous ne pouvons pas être sûrs de l'état futur des données.

3

est ici une autre possibilité, bien que je ne l'ai pas essayé sur Oracle:

select mytable.id, 
     yourtable.id 
from table1 as mytable left outer join 
    (SELECT 2 AS tableid, * 
    FROM table2 
    UNION ALL 
    SELECT 1, * 
    FROM table3) as yourtable 
    ON mytable.id = yourtable.id 
    AND tableid = CASE WHEN mytable.id = 2 THEN 2 ELSE 1 END