web-dev-qa-db-fra.com

Raison de préférer RIGHT JOIN à LEFT JOIN

Si je comprends bien, chaque RIGHT JOIN:

SELECT Persons.*, Orders.*
FROM Orders
RIGHT JOIN Persons ON Orders.PersonID = Persons.ID

peut être exprimé comme LEFT JOIN:

SELECT Persons.*, Orders.*
FROM Persons
LEFT JOIN Orders ON Persons.ID = Orders.PersonID

Mon opinion personnelle est que l'intention de la déclaration:

  • Obtenez d'abord le Persons
  • Développez/répétez ensuite le Persons si nécessaire afin de faire correspondre le Orders

est mieux exprimé par l'ordre de Persons LEFT JOIN Orders que par l'ordre inverse Orders RIGHT JOIN Persons (et je n'utilise jamais RIGHT JOIN Par conséquent).

Y a-t-il des situations où un RIGHT JOIN est préféré? Ou existe-t-il des cas d'utilisation où RIGHT JOIN peut faire quelque chose qui LEFT JOIN ne peut pas?

18
Zev Spitz

Cela dépend de l'exigence que vous essayez de remplir.

Ce n'est pas la même chose de dire: "donnez-moi toutes les personnes et leurs ordres correspondants" que "je veux toutes les commandes avec leurs personnes correspondantes", surtout si vous êtes va utiliser is null pour apporter des lignes sans correspondance correspondante. C'est ce que j'appelle la "table dominante", qui est la table à partir de laquelle je veux récupérer des lignes, même s'il n'y a pas de ligne correspondante de l'autre côté de la jointure.

Regardez ces images et vous remarquerez qu'elles ne sont pas les mêmes:

enter image description here

La source de l'image est cet excellent article .

Mais vous avez raison en ce sens que les deux exigences peuvent être remplies avec l'une ou l'autre jointure en inversant simplement l'ordre des tables dans la jointure.

Mais je suppose que pour les occidentaux habitués à écrire de gauche à droite, il est plus naturel d'utiliser les jointures gauche sur les jointures droites , car nous voyons comme si nous voulons que les jointures soient dans le même sens ou dans le même ordre que les colonnes selected.

Donc, une raison possible de préférer une jointure droite est parce que dans votre culture, vous écrivez de droite à gauche (comme dans les systèmes d'écriture arabe ou hébreu) ​​et vous ont tendance à penser de cette façon, ce qui signifie peut-être dans votre cerveau que les informations textuelles circulent de droite à gauche.

Certains linguistes pensent que votre langue influence votre façon de penser: https://www.Edge.org/conversation/lera_boroditsky-how-does-our-language-shape-the-way-we-think

11
Tulains Córdova

Il n'y a rien (que je sache) qui puisse être fait avec une jointure droite qui ne puisse pas être fait avec une jointure gauche. Mais parfois, la syntaxe avec les jointures gauches est plus laide. Disons que vous disposez des tableaux suivants:

Persons
ID | Name

Orders
ID | CustomerId | other unimportant stuff

SpecialOrderDetails
ID | OrderId | other stuff

Disons que vous devez obtenir une liste de toutes les personnes dans votre base de données et de toutes les commandes qu'elles ont avec des détails de commande spéciaux (nous dirons que toutes les commandes n'ont pas de détails de commande spéciaux). Donc, vous feriez normalement une jointure gauche des gens aux ordres. Mais alors vous devez vous joindre à des détails de commande spéciaux. Si vous utilisez une jointure interne là-bas, cela ferait effectivement de la jointure gauche des personnes aux commandes une jointure interne. IE: c'est ce que vous voulez faire mais ne fonctionne pas (cela exclura toute personne qui n'a pas de commande spéciale):

select p.*, o.*, d.*
from Persons p
left join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Vous pouvez donc le réécrire comme ceci:

--get all the people without a special order
select p.*, NULL, NULL, ... --NULLs placeholders for all the fields from OrderDetails and SpecialOrderDetails
from Persons p
left join Orders o on o.CustomerId = p.Id
left join SpecialOrderDetails d on d.OrderId = o.Id
where o.Id is null 

union

--get all the people with a special order
select p.*, o.*, d.*
from Persons p
inner join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Pas exactement clair (en supposant aucun commentaire), mais il fait le travail. S'il s'agit de quelque chose de plus que ponctuel (c'est-à-dire quelque chose que quelqu'un devra revenir et entretenir un jour), l'utilisation d'une jointure droite pourrait rendre plus claire l'intention.

select p.*, o.*, d.*
from Orders o
inner join SpecialOrderDetails d on d.OrderId = o.Id
right join Persons p on p.Id = o.CustomerId

Ce qui est un peu plus succinct et clair (mais seulement si celui qui le lit comprend les bonnes jointures). Notez que cela peut être écrit avec des jointures gauches, mais cela nécessite une jointure imbriquée (que moins de personnes connaissent probablement que les jointures droites).

select p.*, o.*, d.*
from Persons p
left join Orders o 
    inner join SpecialOrderDetails d on d.OrderId = o.Id
on o.CustomerId = p.Id

À ce stade, il s'agit de choisir ce qui est le plus clair et ce que la plupart des gens comprendront (sauriez-vous comment rechercher cette syntaxe sur Google si vous ne saviez pas qu'elle s'appelait une jointure imbriquée?).

En bref, vous n'avez pas strictement besoin de jointures droites, mais elles pourraient faciliter la lecture.

3
Becuzz