2011-09-01 12 views
21

Desidero essere in grado di unire due tabelle interne in base al risultato di un'espressione.Join interno condizionale

Quello che ho cercato finora:

INNER JOIN CASE WHEN RegT.Type = 1 THEN TimeRegistration ELSE DrivingRegistration AS RReg 
ON 
RReg.RegistreringsId = R.Id 

regt è un join che ho fatto poco prima di questo si uniscono:

INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 

Questo SQL-script non funziona.

Quindi, tutto sommato, se la Type è 1, allora dovrebbe unirsi sul tavolo TimeRegistration altrimenti dovrebbe unirsi su DrivingRegistration.

Soluzione:

Nella mia dichiarazione select ho svolto le seguenti giunzioni:

INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
LEFT OUTER JOIN TimeRegistration AS TReg ON TReg.RegistreringsId = R.Id AND RegT.Type = 1 
LEFT OUTER JOIN DrivingRegistration AS DReg ON DReg.RegistreringsId = R.Id AND RegT.Type <>1 

Poi ho modificato il mio where-clause per produrre il corretto, a seconda del RegType, in questo modo:

WHERE (CASE RegT.Type WHEN 1 THEN TReg.RegistreringsId ELSE DReg.RegistreringsId END = R.Id) 
+0

Non puoi farlo così! 'CASE' non può essere utilizzato per scambiare dinamicamente parti interne ed esterne della query. Queste tabelle hanno le stesse strutture? –

+0

Hai ricevuto un errore? Se è così, che cosa è? – AndrewC

risposta

18

provare a mettere entrambe le tabelle nella query utilizzando del LEFT JOIN

LEFT JOIN TimeRegistration TR ON r.rid = TR.Id AND RegT.type =1 
LEFT JOIN DrivingRegistration DR ON r.rid = DR.Id AND RegT.type <>1 

Ora, in selezionate clausola, utilizzare

CASE RegType.Type WHEN 1 THEN TR.SomeField ELSE DR.someField END as SomeField 

L'altra opzione è quella di utilizzare SQL dinamico

+0

Sembra che le grandi menti pensano allo stesso modo di David, basta digitare più velocemente .... – Sparky

+0

Ninja fingers ... – David

+0

Awesome, sia i suggerimenti di Sparky che di David hanno aiutato! Modificherà la mia domanda su ciò che ho fatto per farlo funzionare. – KristianB

8

Probabilmente è necessario eseguire due giunzioni a sinistra, una su TimeRegistration e uno su DrivingRegistration, e restituire i campi desiderati dalla join appropriato tavolo qualcosa di simile:

LEFT JOIN TimeRegistration ON TimeRegistration.RegistreringsId = R.Id 
LEFT JOIN DrivingRegistration ON DrivingRegistration.RegistreringsId = R.Id 

e si seleziona dichiarazione sarebbe qualcosa di simile a questo:

SELECT CASE WHEN RegT.Type = 1 THEN TimeRegistration.Foo ELSE DrivingRegistration.Bar END 

Mi piace quello che' sto cercando di fare, ma non credo che SQL sia così intelligente.

1
SELECT 
    R.foo, tr.bar 
FROM 
    SomeTable AS R 
    INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
              AND RegT1.Type = 1 
    INNER JOIN TimeRegistration AS tr ON /* whatever */ 

UNION 

SELECT 
    R.foo, dr.bar 
FROM 
    SomeTable AS R 
    INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
              AND RegT1.Type = 2 
    INNER JOIN DrivingRegistration AS dr ON /* whatever */ 
+0

+1 anche se probabilmente sarà necessario "UNION ALL". Se le tabelle sono compatibili con Union, queste potrebbero essere in una CTE con una colonna 'type' per evitare di ripetere la logica' JOIN', anche se non sono sicuro di come sarebbero i piani di esecuzione. –

+0

@ Martin: con gli indici corretti, i due join dovrebbero essere molto veloci. Presupposto dal momento che le due tabelle di destinazione sono diverse, un ALL UNIONE non sarebbe necessario. – Tomalak

Problemi correlati