web-dev-qa-db-fra.com

Jointure externe gauche gauche sur plusieurs colonnes

Selon cette triche de jointure SQL , une jointure externe gauche sur une colonne est la suivante: 

SELECT *
  FROM a
  LEFT JOIN b 
    ON a.foo = b.foo
  WHERE b.foo IS NULL 

Je me demande à quoi ressemblerait une jointure sur plusieurs colonnes. Devrait-il s'agir d'un OR ou d'un AND dans la clause WHERE?

SELECT *
  FROM a
  LEFT JOIN b 
    ON  a.foo = b.foo
    AND a.bar = b.bar
    AND a.ter = b.ter
WHERE b.foo IS NULL 
  OR  b.bar IS NULL 
  OR  b.ter IS NULL

ou 

SELECT *
  FROM a
  LEFT JOIN b 
    ON  a.foo = b.foo
    AND a.bar = b.bar
    AND a.ter = b.ter
WHERE b.foo IS NULL 
  AND b.bar IS NULL 
  AND b.ter IS NULL

?

(Je ne pense pas que ce soit le cas, mais dans le cas contraire, le moteur de base de données est celui de Vertica)

(Je parie sur le OR)

5
François M.

Cela dépend si les colonnes peuvent être annulées, mais en supposant qu'elles ne le soient pas, cocher l'une d'elles fera l'affaire:

SELECT *
  FROM a
  LEFT JOIN b 
    ON  a.foo = b.foo
    AND a.bar = b.bar
    AND a.ter = b.ter
WHERE b.foo IS NULL -- this could also be bar or ter

En effet, après une jointure réussie, les trois colonnes auront une valeur non nulle.

Si certaines de ces colonnes étaient nullables et que vous souhaitez vérifier si l'une d'entre elles avait une valeur après la jointure, votre première approche (OR) serait OK.

12
Cristian Lupascu

Vous pouvez utiliser n’importe quelle combinaison de critères pour vous joindre:

SELECT *
FROM a
LEFT JOIN b ON a.foo = b.foo AND a.bar = b.bar AND a.ter = b.ter

La clause WHERE n'a rien à voir avec la jointure elle-même . Le WHERE b.foo IS NULL dans la première requête renverra tous les enregistrements de a qui n'avaient aucun enregistrement correspondant dans b ou lorsque b.foo était null.

1