2010-03-22 18 views
5

Mam scenariusz, w którym chcę włączyć dwie różne tabele w łączeniu zewnętrznym. Wygląda to tak: -Używanie instrukcji CASE w LEWEJ ZEWNĘTRZNEJ JOIN w 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) 

... ale to nie działa. Jakieś sugestie?

+2

To może być warta ponownego rozpatrzenia projekt bazy danych. Jeśli zarówno tabela 2, jak i tabela 3 mają takie same lub podobne schematy, dlaczego są to różne tabele? –

+0

Warto ponownie przeanalizować Twój przykład. Wygląda na to, że miksuje się alias/tablename. – jva

+0

Po prostu dołącz do OBU tabeli i przenieś część CASE do listy kolumn – user38123

Odpowiedz

4

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

Dla wierszy, gdzie mt.id wynosi 2, ale istnieje wiele dopasowań w yt2 dla tego id, może to wygenerować duplikaty. –

+0

@Gary: To prawda, pomyślałem o tym podczas wysyłania, ale postanowiłem opublikować zapytanie pasujące do OP dosłownie. –

+0

Dzięki. to działało dobrze i nie, nie powinno być żadnych duplikatów wartości, więc to również sobie z tym poradziło. –

1

To zapytanie dołącza rekordy z tabeli EMP albo tabeli DEPT lub stole SPECIAL_OPS, w zależności od wartości 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> 

Zawarłem filtr EMP.DEPTNO w klauzulach ON. Może to być niepotrzebne, jeśli dane w tabelach są wyłączne (tj. DEPTNO = 30 może dołączyć tylko do DEPT, a DEPTNO = 50 może dołączyć tylko do SPECIAL_OPS). Jeśli jednak identyfikator może pojawić się w obu tabelach, to również musi być wyraźny. Poza tym, podkreślanie naszego zamiaru jest zawsze dobrą praktyką. Poza wszystkim innym nie możemy mieć pewności co do przyszłego stanu danych.

3

Oto kolejna możliwość, choć nie próbowałem go na 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 
Powiązane problemy