J'ai fait un script qui récolte les adresses MAC des ports de commutation et les met dans une base de données. Je l'insère dans une table d'importation à copier plus tard à la table réelle. Tout va bien. Maintenant, j'écris la requête pour trouver quelles adresses MAC sont nouvelles. Donc, j'ai besoin des rangées dans la table d'importation qui ne sont pas dans la table de destination. Une jointure extérieure gauche a du sens:
select *
from SwitchportMac_import i
left outer join SwitchportMac sm
on sm.switch = i.switch and sm.port = i.port and sm.mac = i.mac
Cela renvoie également des rangées dans i
qui correspondent à sm
. Bien sûr, je peux ajouter un where sm.id is null
mais je suis graphégassé.
Donc soit:
Si c'est le premier, je vais jeter le DDL et la comprendre mais j'ai peur que c'est le second. Le mot clé externe existe-t-il juste pour me confondre?
LEFT JOIN
Et LEFT OUTER JOIN
Sont synonymes tellement excuses mais cela ressemble à l'option 2 :-)
La jointure "extérieure" (qui conserve des lignes inégalées) est par opposition à "interne" (qui ne le fait pas).
Il y a trois saveurs de jointure extérieure. Gauche, droite, pleine (dépendante sur lesquelles des lignes inégalées doivent être préservées).
Comme SQL n'a pas de syntaxe de jointure directe pour aucun autre type de jointure (comme la jointure anti-semi gauche/droite), aucune ambiguïté ne permet de permettre le mot-clé OUTER
peut être facultatif dans la grammaire.
Le LEFT ANTI SEMI JOIN
Cela ressemble à ce que vous attendiez LEFT OUTER
Faire. Vous pouvez mettre en œuvre cela ne variété de façons . Habituellement NOT EXISTS
Est préféré mais vous pouvez utiliser LEFT OUTER JOIN
En conjonction avec IS NULL
Pour ne conserver que les non correspondants.
Tout cela est confirmé dans le " type de jointure " section de la documentation
LEFT [ OUTER ]
Spécifie que toutes les lignes de la table de gauche ne répondant pas à la condition de jointure sont incluses dans le jeu de résultats et les colonnes de sortie de l'autre table sont définies surNULL
en plus de toutes les lignes retournées par le jointure interne.
Les crochets autour du [OUTER]
Signifie simplement que cela est facultatif mais néanmoins la même définition s'applique.
Ce serait mon moyen préféré d'obtenir ce que vous voulez, en utilisant une sous-requête corrélée à l'exercice. En supposant que vous avez un index sur les deux tables sur le commutateur, le port et le Mac, cela devrait également être une bonne performance.
SELECT *
FROM SwitchportMac_import i
WHERE NOT EXISTS (
SELECT TOP (1) 1
FROM SwitchportMac sm
WHERE sm.switch = i.switch
and sm.port = i.port
and sm.mac = i.mac
)
de SwitchPortmac_IMPORT I GAUCHE OUTER REJOINDRE SWNTPORTMAC SM
Cela renvoie des rangées dans I qui correspondent à SM.
Correct. C'est exactement ce qu'est une jointure à gauche [externe] fait - cela vous obtient tout dans la table "gauche" (i) s'il peut trouver une ligne correspondante dans la table "SM)".
Pour obtenir des "nouveaux" articles (ceux qui apparaissent dans la table "gauche" mais pas le "droit"), vous besoin de pour inclure que "est Null" Test aussi bien =. Ceci est communément appelé "une jointure d'exclusion".
where sm.id is null
est nécessaire pour correspondre aux rangées qui n'existent pas dans la jointure.
Les jointures de gauche sont toujours OUTER
donc son sucre syntaxique inventé par le comité. Ils envisagent de vous déranger et d'autres à l'avance. Vous n'êtes pas un idiot, la confusion a été mise en œuvre comme prévu.
JOIN DE GAUCHE dit "Prenez toutes les lignes de la gauche I.E. Table précédente I.E. SwitchPortMAC_IMPORT". Vous ne voulez pas toutes les lignes de cette table, seuls ceux qui ne correspondent pas.
Ajouter le IS NULL fonctionnera. Je pense qu'un n'existe pas, cela conviendrait mieux à vos besoins.