web-dev-qa-db-fra.com

Quel est le point de l'extérieur dans une jointure?

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:

  • Je suis un idiot et j'ai manifestement faux
  • Je suis un idiot et j'ai expliqué et la compréhension se joint mal pendant 20 ans

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?

6
user189695

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 sur NULL 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.

10
Martin Smith

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
)
4
Jonathan Fite

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".

3
Phill W.

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.

1
danblack

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.

1
Michael Green