2010-03-22 13 views
5

Ho uno scenario in cui voglio attivare due tabelle diverse in un join esterno. Va qualcosa di simile a questo: -Utilizzo delle istruzioni CASE in LEFT OUTER JOIN in 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) 

... ma non funziona. Eventuali suggerimenti?

+2

Potrebbe valere la pena di riesaminare la struttura del database. Se sia table2 che table3 hanno schemi uguali o simili, perché sono tabelle diverse? –

+0

Vale anche la pena riesaminare il tuo esempio. Sembra esserci un mix di alias/tablename. – jva

+0

Basta unirsi alle tabelle BOTH e spostare la parte CASE nell'elenco delle colonne – user38123

risposta

4

Usa (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

Per le righe in cui mt.id è 2 ma ci sono più corrispondenze in yt2 per quell'id, questo potrebbe generare duplicati. –

+0

@Gary: È vero, ci ho pensato durante la pubblicazione ma ho deciso di pubblicare una query che corrispondesse all'OP letteralmente. –

+0

Grazie. questo ha funzionato bene e no, non ci dovrebbero essere valori duplicati, quindi anche questo ha gestito questo. –

1

Questa interrogazione unisce i record dalla tabella EMP sia al tavolo DEPT o la tabella SPECIAL_OPS, a seconda del valore di 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> 

Ho incluso il filtro su EMP.DEPTNO nelle clausole ON. Questo potrebbe non essere necessario se i dati nelle tabelle sono esclusivi (ad esempio, DEPTNO = 30 poteva solo unirsi a DEPT e DEPTNO = 50 poteva solo unirsi a SPECIAL_OPS). Tuttavia, se l'identificatore può apparire in entrambe le tabelle, è altrettanto esplicito. Inoltre, rendere chiaro il nostro intento è sempre una buona pratica. A parte tutto, non possiamo essere sicuri del futuro stato dei dati.

3

Ecco un'altra possibilità, anche se non ho provato su 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