2013-04-13 13 views
6

Non sono sicuro se ho perso per cercare correttamente, ma non ho potuto ottenere la domanda esatta come la miaDeterminare tabella da unire in base alle condizioni

Questo è qualcosa di simile, ma non è esatto

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

in realtà io voglio decidere con quale tabella join in base al parametro passato alla stored procedure, case when non ha funzionato

Tipo di

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

Table2 e Table3 ha stessa struttura

risposta

7

mi viene in mente un paio di opzioni:

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: dinamica 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 e sottoquery.

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 

Per quest'ultimo ci si controlla il piano l'ottimizzatore crea per vedere se si tratta di prestazioni OK saggio.

Sembra che tu stia cercando il riutilizzo del codice, quindi forse l'opzione 2 è la migliore. T-SQL in realtà non si presta a questo tipo di polimorfismo, ma in alcuni casi è possibile utilizzare soluzioni alternative.

Facendo un passo indietro, una domanda da porsi è, se i tavoli hanno la stessa struttura, forse dovresti semplicemente usare una tabella? Quindi è possibile utilizzare @Parameter per filtrare semplicemente le righe necessarie invece di provare a creare query dinamiche.

Vale anche la pena notare che in situazioni come questa è possibile gestire la generazione del codice a livello di applicazione con ORM e simili.

+0

Grazie Ian, in realtà la struttura della tabella è lo stesso ma i dati è diverso in base alle condizioni, 'Table2' è la tabella reale dal database mentre' Table3' è una tabella restituito da una funzione con la stessa struttura –

+0

@PawanNogariya, abbastanza giusto, risponde alla domanda su come combinare le cose in un unico tavolo. Tutto il resto vale: ho aggiunto anche un'altra opzione, usando 'UNION ALL' per combinarli in una subquery da utilizzare nel resto della query. Spero che almeno uno aiuti! –

1

Prova questo:

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

Penso che intendessi 'quando selection = 2 then t2.ExtraField' invece di' when selection = 2 then t1.ExtraField' :) –

+0

@PawanNogariya: grazie; corretto. –

+0

Tranne che 'ExtraField' non può essere referenziato in questo caso. Puoi mettere l'intera cosa in una sottoselezione e filtrare su 'ExtraField' nella selezione esterna. Oppure, se la versione utilizzata è SQL Server 2005 o successiva, è possibile calcolare 'ExtraField' in CROSS APPLY, in questo modo riferimento a' ExtraField' in WHERE sarebbe valido. –

Problemi correlati