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

18

Si je comprends bien, tous 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
  • Puis développez / répétez le Personssi nécessaire afin de faire correspondre leOrders

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

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

Zev Spitz
la source
12
Je ne me souviens pas d'un cas où je voulais une bonne jointure. J'ai eu des cas où le plan d'exécution d'une requête a inversé une jointure gauche dans une jointure droite pour des raisons de performances. Mais du point de vue de l'écriture de code pur, non, je ne me souviens pas d'avoir écrit une bonne jointure.
Brandon
2
Je ne vois pas cela comme une question sur "l'explication, l'écriture ou le débogage du code". C'est demander pourquoi une langue a deux caractéristiques qui font apparemment la même chose, s'il y a réellement une différence entre elles, et si ce n'est pas le cas où celle "non évidente" serait préférée.
Philip Kendall
1
Non, une jointure gauche capture presque toujours ce dont vous avez besoin le plus succinctement et est plus facile à raisonner. Sur mon lieu de travail, nous avons en fait une norme en place pour empêcher les jointures droites car il n'y a jamais de cas où elles sont nécessaires (c'est-à-dire qu'elles peuvent toujours être remplacées par la jointure gauche opposée).
mgw854
8
J'ai réinitialisé les votes serrés - cette question est sur le sujet ici, car la compréhension de la différence entre les jointures affecte la conception logicielle (la conception de la base de données fait partie de la conception logicielle, tout comme les algorithmes qui peuvent interroger les bases de données). Il peut également être sur le sujet chez les administrateurs de base de données , et il peut également y avoir un doublon.
Thomas Owens
1
Je ne sais pas si vous suggérez que RIGHT JOINc'est recommandé ou plus courant. Si c'est votre prémisse, c'est incorrect. Je ne peux pas penser à un moment où j'ai jamais vu la bonne jointure utilisée dans le code ni dans les exemples. C'est JOINou LEFT OUTER JOIN. Dans de rares cas, vous pourriez voir un FULL OUTER JOIN.
JimmyJames

Réponses:

12

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 commandes correspondantes" que "je veux toutes les commandes avec leurs personnes correspondantes" , en particulier si vous allez utiliser is nullpour 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:

entrez la description de l'image ici

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 gauches sur les jointures droites , car nous voyons comme si nous voulions que les jointures soient dans le même sens ou dans le même ordre que les selectcolonnes ed.

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 avez 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

Tulains Córdova
la source
1
J'avais commencé à penser dans ce sens, mais je ne pense pas que ce soit correct. J'ai commencé à imaginer écrire SQL en hébreu (ce que je n'ai jamais fait). OK: justifié à droite, de droite à gauche, de haut en bas. Vous mentionnerez toujours le tableau A d'abord, puis le tableau B. Avec une jointure droite, vous excluez ensuite (en particulier dans le cas nul) la plupart ou la totalité du tableau mentionné en premier. Je pense que l'esprit humain a tendance à s'associer d' abord avec le primaire et le plus important . Cela se produit quelle que soit la direction d'écriture. Vous pouvez les appeler "FIRST JOIN" et "SECOND JOIN" et ce biais persiste.
Mike prend en charge Monica
J'ai inclus un lien vers l'image que vous avez montrée ci-dessous.
Jon Raynor
@ Mike, je ne suggère pas aux gens d'écrire SQL en arabe ou en hébreu. Juste que l'orientation de votre langue maternelle pourrait être une raison pour laquelle vous préférez les jointures droites. Mais ce n'est qu'une possibilité. Je trouve les jointures gauches plus naturelles.
Tulains Córdova
Maintenant, j'ai donné le crédit dû au créateur de l'image. Je l'ai depuis des années dans ma HD et je ne me souvenais pas d'où cela venait,
Tulains Córdova
Je parle couramment l'hébreu et je trouve toujours LEFT JOINplus naturel.
Zev Spitz
3

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 cela 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 correctes, mais elles pourraient faciliter la lecture.

Becuzz
la source
Je pense que vous êtes peut-être juste droitier.
Robert Harvey
Je ne suis pas pourquoi vous ne pouvez pas écrire plusieurs gauche rejoint dans ce cas: SELECT p.*, o.*, d.* FROM Persons p LEFT JOIN Orders o ON o.CustomerID = p.ID LEFT JOIN SpecialOrders d ON o.Id = d.OrderID.
Zev Spitz
@RobertHarvey Je le suis, mais je ne suis pas sûr de ce que les mains ont à voir avec cela.
Becuzz
@ZevSpitz Peut-être que ce que j'ai écrit n'était pas clair, mais l'idée était que vous ne vouliez les champs des commandes que s'il existe un enregistrement de détails de commande spécial, c'est-à-dire. ne les rejoindre que si la paire existe.
Becuzz
-1

Je pouvais voir un RIGHT JOIN utilisé à des fins de réplication / fusion. Disons que j'ai deux tables A et B. A est à gauche et B à droite. Disons que je voulais répliquer des données entre ces deux tables pour les rendre équivalentes.

Si je voulais montrer toutes les données qui étaient en A mais pas en B, ce serait une jointure GAUCHE. Si je voulais montrer toutes les données en B qui n'étaient pas en A, elles se rejoindraient à DROITE.

Ainsi, LEFT et RIGHT sont parfois utiles lors de la fusion et de la réplication de données pour garder les choses en perspective.

En dehors de cela, je ne vois aucune autre raison d'utiliser une jointure DROITE car toutes les jointures DROITES peuvent être converties en jointures GAUCHE ou vice versa, toutes les jointures GAUCHE peuvent être converties en jointures DROITES selon la façon dont les tables sont ordonnées ou visualisées. Ce serait donc une question de préférence dans d'autres cas.

Voici un bon lien pour visualiser les jointures SQL.

http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

Jon Raynor
la source
-1

la jointure gauche n'est pas l'opposé de la jointure droite, vérifiez le cas suivant qui donne des résultats différents

select * from 
(select 1 as x  where 1=1) a left join 
(select 1 as x  where 1=0) b on a.x=b.x inner join 
(select 1 as x  where 1=1) c on b.x=c.x

select * from 
(select 1 as x where 1=1) c inner join 
(select 1 as x where 1=0) b on c.x=b.x right join 
(select 1 as x where 1=1) a on b.x=a.x

les tables b anc c sont toujours jointes à l'intérieur mais dans la première a est joint à gauche aux autres et sur la seconde a est joint à droite

la jointure gauche ne renvoie aucune ligne tandis que la jointure droite renvoie une ligne

jacob s
la source
cela ressemble plus à un commentaire tangentiel, voir Comment répondre
moucher
-2

Il n'y a jamais de raison de préférer RIGHT JOIN, et LEFT JOINc'est beaucoup plus clair:

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

car il vous permet de voir immédiatement quelle table est interrogée. Alors qu'avec RIGHT JOIN:

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

le premier tableau est écrit après le JOIN.

D'après mon expérience, je n'en ai jamais vu RIGHT JOIN.

kirie
la source
1
Qu'est-ce que cela ajoute à la question? La question n'est pas quelle est la différence? ; La question est pourquoi devrais-je utiliser RIGHT JOIN? .
Zev Spitz
@ZevSpitz Vous demandez la raison de préférer laquelle, je vous donne une raison. Quel cas d'utilisation n'a pas d'importance car c'est une question de goût.
kirie