2011-06-14 2 views
1

Quelle est la méthode correcte pour joindre (intérieurement) deux tables lorsque le On-Clause-Criteria dépend de l'une des deux colonnes? Ainsi, Table1 doit se joindre lorsque l'une des deux colonnes est égale à une colonne de Table2.«Critères Or» supplémentaires dans la clause ON d'une jointure interne

Jetez un oeil à la T-SQL simplifiée suivante voir ce que je veux dire et si je l'avais fait dans le bon sens:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
GO 
BEGIN TRANSACTION; 
GO 
create table #RMA1(
    SSN_IN varchar(15), 
    SSN_OUT varchar(15) 
) 
create table #RMA2(
    SSN_NUMBER varchar(15), 
) 
INSERT INTO #RMA1 VALUES('012590001827977', '351600035840752'); 
INSERT INTO #RMA1 VALUES('332653577440220', '351600035804105'); 
INSERT INTO #RMA1 VALUES('350302031074780', '350302031074780'); 
INSERT INTO #RMA1 VALUES('351649036778024', '351806033440194'); 

INSERT INTO #RMA2 VALUES('012590001827977'); 
INSERT INTO #RMA2 VALUES('332653577440220'); 
INSERT INTO #RMA2 VALUES('350302031074780'); 
INSERT INTO #RMA2 VALUES('351649036778024'); 
INSERT INTO #RMA2 VALUES('351600035840752'); 
INSERT INTO #RMA2 VALUES('351600035804106'); 

SELECT SSN_IN,SSN_OUT,SSN_NUMBER FROM #RMA1 INNER JOIN 
#RMA2 ON (#RMA1.SSN_IN = #RMA2.SSN_NUMBER OR 
      #RMA1.SSN_Out = #RMA2.SSN_NUMBER) 

DROP TABLE #RMA1; 
DROP TABLE #RMA2; 
GO 
COMMIT TRANSACTION; 
GO 

Résultat:

SSN_IN   SSN_OUT   SSN_NUMBER 
012590001827977 351600035840752 012590001827977 
012590001827977 351600035840752 351600035840752 
332653577440220 351600035804105 332653577440220 
350302031074780 350302031074780 350302031074780 
351649036778024 351806033440194 351649036778024 

Q: Est-il correct de joindre les tables avec un OR dans la ON -Clause de la jointure interne?

Il renvoie correctement 5 enregistrements et supprime le dernier enregistrement de # RM2 car il n'est ni dans #RM1.SSN_IN ni dans #RM1.SSN_OUT. Mais je me sens mal que cela ne donne pas toujours le bon résultat. En fait, la performance de la requête complète réelle est très pauvre.

Répondre

3

Le résultat devrait être correct, mais votre observation est correcte que la performance est mauvaise. La base de données ne peut pas utiliser efficacement les index car elle doit analyser l'index et effectuer une opération arithmétique pour chaque élément.

Faire deux à gauche rejoint la place laisserait la base de données de mieux utiliser les index:

select 
    SSN_IN, 
    SSN_OUT, 
    coalesce(T1.SSN_NUMBER, T2.SSN_NUMBER) as SSN_NUMBER 
from 
    #RMA1 
    left join #RMA2 as T1 on #RMA1.SSN_IN = T1.SSN_NUMBER 
    left join #RMA2 as T2 on #RMA1.SSN_Out = T2.SSN_NUMBER 
where 
    T1.SSN_NUMBER is not null or T2.SSN_NUMBER is not null 
Questions connexes