2013-04-13 15 views
6

Nie jestem pewien, czy Tęskniłam poprawnie szukać, ale nie mogłem uzyskać dokładny pytanie jak kopalniaUstal stół do przyłączenia się na podstawie stanu

To jest coś podobnego, ale nie jest dokładna

https://stackoverflow.com/questions/11533636/determining-which-table-to-join-to

Właściwie chcę zdecydować, z której tabeli do przyłączenia się w oparciu o parametr przekazany do procedury przechowywanej, case when nie działa

Rodzaju

select * from Table1 
     left join (case when @Parameter<>NULL Then Table2 else Table3 end) final 
     on Table1.Col1 = final.Col1 

Tabela 2 i Table3 ma taką samą strukturę

Odpowiedz

7

Mogę myśleć o kilka opcji:

1: IF ... ELSE

IF @Parameter IS NULL 

    SELECT * 
    FROM T1 
    INNER JOIN T2 ON T1.ID = T2.ID 

ELSE 

    SELECT * 
    FROM T1 
    INNER JOIN T3 ON T1.ID = T3.ID 

2: Dynamiczne T-SQL

DECLARE @SQL NVARCHAR(MAX); 

SELECT @SQL = N'SELECT * 
    FROM T1 
    INNER JOIN ' + CASE WHEN @Parameter IS NULL THEN N'T2 t' ELSE N'T3 t' END 
    + N' ON T1.ID = t.ID'; 

EXEC sp_executesql @SQL; 

3: UNION ALL i podzapytanie.

SELECT * 
    FROM T1 
    INNER JOIN 
    (
     SELECT * 
     FROM T2 
     WHERE @Parameter IS NULL 
     UNION ALL 
     SELECT * 
     FROM T3 
     WHERE @Parameter IS NOT NULL 
    ) t ON T1.ID = t.ID 

W tym ostatnim przypadku należy sprawdzić plan, jaki tworzy optymalizator, aby sprawdzić, czy jego wydajność jest odpowiednia.

Wygląda na to, że szukasz ponownego użycia kodu, więc może opcja 2 jest najlepsza. T-SQL tak naprawdę nie nadaje się do tego rodzaju polimorfizmu, ale w niektórych przypadkach można użyć obejścia.

Cofając się, jedno pytanie, które należy zadać, to, czy stoły mają taką samą strukturę, może powinieneś po prostu użyć jednej tabeli? Następnie możesz użyć @Parameter, aby odfiltrować żądane wiersze zamiast próbować tworzyć zapytania dynamiczne.

Warto również zauważyć, że w takich sytuacjach można obsłużyć generowanie kodu w warstwie aplikacji za pomocą ORM i tym podobnych.

+0

Dzięki Ian, faktycznie struktura tabeli jest taka sama, ale danych jest różny w zależności od stanu, 'Table2' jest rzeczywista tabela z bazy danych, podczas gdy' Table3' jest stół wrócił z funkcji o tej samej strukturze –

+0

@PawanNogariya, wystarczająco dobrze, odpowiada na pytanie o łączenie rzeczy w jeden stół. Cała reszta ma zastosowanie - dodałem też inną opcję, używając "UNION ALL", aby połączyć je w jedno podzapytanie do wykorzystania w pozostałej części zapytania. Mam nadzieję, że przynajmniej jeden pomoże! –

1

Spróbuj tego:

select * 
from (
    select data.*, 
    case when selection=1 then t1.ExtraField 
     when selection=2 then t2.ExtraField 
     when selection=3 then t3.ExtraField 
     else NULL 
    end as ExtraField 
    from data 
    left join t1 on t1.key = data.key and selection=1 
    left join t2 on t2.key = data.key and selection=2 
    left join t3 on t3.key = data.key and selection=3 
) T 
where ExtraField is not NULL 
+0

Myślę, że miałeś na myśli 'gdy selection = 2 then t2.ExtraField' zamiast' when selection = 2 then t1.ExtraField' :) –

+0

@PawanNogariya: thank you; poprawione. –

+0

Z wyjątkiem 'ExtraField' nie można się odwoływać w tym przypadku. Możesz umieścić wszystko w podselekcji i filtrować "ExtraField" w zewnętrznym wyborze. Lub, jeśli używaną wersją jest SQL Server 2005 lub nowszy, możesz obliczyć 'ExtraField' w CROSS APPLY, w ten sposób odniesienie do' ExtraField' w WHERE będzie poprawne. –

Powiązane problemy