web-dev-qa-db-fra.com

Quand ou pourquoi utiliseriez-vous une jointure externe droite au lieu de gauche?

Wikipedia États:

"En pratique, les jointures externes droites explicites sont rarement utilisées, car elles peuvent toujours être remplacées par des jointures externes gauche et ne fournissent aucune fonctionnalité supplémentaire."

Quelqu'un peut-il prévoir une situation dans laquelle ils ont préféré utiliser la notation DROITE et pourquoi? Je ne peux pas penser à une raison pour l'utiliser jamais. Pour moi, cela ne rendrait jamais les choses plus claires.

Edit: Je suis un vétéran d'Oracle en train de prendre la résolution du Nouvel An pour me sevrer de la syntaxe (+). Je veux bien faire les choses

45
DCookie

La seule raison pour laquelle je peux penser à utiliser RIGHT OUTER JOIN est d’essayer de rendre votre code SQL plus auto-documenté.

Vous voudrez peut-être utiliser des jointures à gauche pour les requêtes ayant des lignes nulles du côté dépendant (plusieurs) des relations un à plusieurs et des jointures droites pour les requêtes générant des lignes nulles du côté indépendant.

Cela peut également se produire dans le code généré ou si les conditions de codage d'un magasin spécifient l'ordre de déclaration des tables dans la clause FROM.

31
Yes - that Jake.

Je n'ai jamais utilisé right join auparavant et je n'ai jamais pensé pouvoir en avoir réellement besoin, et cela semble un peu anormal. Mais après y avoir réfléchi, cela pourrait être vraiment utile dans la situation où il est nécessaire de joindre une table avec l'intersection de plusieurs tables, de sorte que vous ayez des tables comme celle-ci:

enter image description here

Et je veux obtenir un résultat comme ça:

enter image description here

Ou, en SQL (MS SQL Server):

declare @temp_a table (id int)
declare @temp_b table (id int)
declare @temp_c table (id int)
declare @temp_d table (id int)

insert into @temp_a
select 1 union all
select 2 union all
select 3 union all
select 4

insert into @temp_b
select 2 union all
select 3 union all
select 5

insert into @temp_c
select 1 union all
select 2 union all
select 4

insert into @temp_d
select id from @temp_a
union
select id from @temp_b
union
select id from @temp_c

select *
from @temp_a as a
    inner join @temp_b as b on b.id = a.id
    inner join @temp_c as c on c.id = a.id
    right outer join @temp_d as d on d.id = a.id

id          id          id          id
----------- ----------- ----------- -----------
NULL        NULL        NULL        1
2           2           2           2
NULL        NULL        NULL        3
NULL        NULL        NULL        4
NULL        NULL        NULL        5

Donc, si vous passez au left join, les résultats ne seront pas les mêmes.

select *
from @temp_d as d
    left outer join @temp_a as a on a.id = d.id
    left outer join @temp_b as b on b.id = d.id
    left outer join @temp_c as c on c.id = d.id

id          id          id          id
----------- ----------- ----------- -----------
1           1           NULL        1
2           2           2           2
3           3           3           NULL
4           4           NULL        4
5           NULL        5           NULL

La seule façon de procéder sans la jointure droite consiste à utiliser une expression de table commune ou une sous-requête

select *
from @temp_d as d
    left outer join (
        select *
        from @temp_a as a
            inner join @temp_b as b on b.id = a.id
            inner join @temp_c as c on c.id = a.id
    ) as q on ...
16
Roman Pekar

B RIGHT JOIN A est identique à A LEFT JOIN B

B RIGHT JOIN A lit comme suit: B ON RIGHT, PUIS JOINS A. signifie que A est dans la partie gauche du jeu de données. tout comme A LEFT JOIN B

Aucune performance ne peut être obtenue si vous réorganisez les JOINTS GAUCHE en DROITS.

La seule raison pour laquelle on peut utiliser RIGHT JOIN, c’est si vous êtes un type de personne qui aime penser de l’intérieur (sélectionnez * dans l’en-tête de jointure de droite). C’est comme d’autres comme le petit boutien, d’autres comme le big-endian, d’autres comme le design descendant, les autres comme le dessin ascendant.

L'autre est que si vous avez déjà une énorme requête pour laquelle vous souhaitez ajouter une autre table, si vous avez du mal à réorganiser la requête, il vous suffit de brancher la table à une requête existante à l'aide de RIGHT JOIN.

15
Michael Buen

La seule fois où je penserais à une jointure externe droite, c’est si je fixais une jointure complète, et il m'est arrivé que le résultat contienne tous les enregistrements de la table de droite. Même si je suis paresseux, cependant, je serais probablement si énervé que je le réorganiserais pour utiliser une jointure gauche.

Cet exemple de Wikipedia montre ce que je veux dire:

SELECT *  
FROM   employee 
   FULL OUTER JOIN department 
      ON employee.DepartmentID = department.DepartmentID

Si vous ne remplacez que le mot FULL par RIGHT, vous avez une nouvelle requête, sans avoir à permuter l'ordre de la clause ON.

6
Bill the Lizard
SELECT * FROM table1 [BLANK] OUTER JOIN table2 ON table1.col = table2.col

Remplacez [BLANK] par:

LEFT - si vous voulez tous les enregistrements de table1 même s'ils n'ont pas de col qui correspond à ceux de table2 (sont également inclus les enregistrements de table2 avec des correspondances)

DROIT - si vous voulez tous les enregistrements de table2 même s'ils n'ont pas de col qui correspond à ceux de table1 (sont également inclus les enregistrements de table1 avec des correspondances)

COMPLET - si vous voulez tous les enregistrements de table1 et de table2

De quoi tout le monde parle-t-il? Ils sont les mêmes? Je ne pense pas.

3
Andrew G. Johnson

Je n'ai pas vraiment beaucoup réfléchi à la bonne jointure, mais je suppose qu'en moins de 20 ans d'écriture de requêtes SQL, je n'ai trouvé aucune justification valable pour en utiliser une. J'imagine que j'en ai certainement vu beaucoup venir des cas où les développeurs ont utilisé des générateurs de requêtes intégrés. 

Chaque fois que j'en rencontrais un, je réécrivais la requête pour l'éliminer. J'ai découvert qu'ils nécessitaient trop d'énergie mentale supplémentaire pour apprendre ou réapprendre si vous n'aviez pas consulté la requête depuis un certain temps sans que cela se produise. Il n’a pas été rare que l’objet de la requête soit perdu ou renvoie des résultats incorrects - et c’est généralement cette inexactitude qui m’a amené à demander à vérifier pourquoi les requêtes ne fonctionnaient pas. 

En réfléchissant à cela, une fois que vous introduisez une jointure à droite, vous avez maintenant ce que je considérerais comme des branches de logique en concurrence qui doivent se rencontrer au milieu. Si des exigences/conditions supplémentaires sont introduites, ces deux branches peuvent être davantage étendues et vous devez gérer une complexité accrue pour vous assurer qu'une branche ne génère pas de résultats incorrects.

En outre, une fois que vous avez créé une jointure droite, d’autres développeurs moins expérimentés travaillant ultérieurement sur la requête peuvent simplement intégrer d’autres tables à la partie droite de la requête et, ce faisant, développer des flux logiques concurrents qui doivent encore se rencontrer. le milieu; ou dans certains cas que j'ai vus, commencez à imbriquer des vues parce qu'elles ne veulent pas toucher à la logique d'origine, peut-être en partie parce qu'elles risquent de ne pas comprendre la requête ou les règles de gestion en vigueur qui ont motivé la logique.

2
mattpm

Les seules fois où j'ai utilisé une jointure droite, c’est lorsque j’ai envie d’examiner deux ensembles de données et que j’ai déjà les jointures dans un ordre spécifique pour la jointure gauche ou la jointure interne d’une requête précédemment écrite. Dans ce cas, supposons que vous souhaitiez voir comme un ensemble de données les enregistrements non inclus dans la table a mais dans la table b et dans un autre ensemble, les enregistrements non dans la table b mais dans la table a. Même dans ce cas, j'ai tendance à ne faire cela que pour gagner du temps dans la recherche, mais cela changerait si le code était exécuté plus d'une fois.

2
HLGEM

Les instructions SQL, en plus d'être correctes, doivent être aussi faciles à lire et concises que possible (car elles représentent des actions atomiques uniques, et votre esprit doit les suivre complètement pour éviter des conséquences imprévues.) Parfois, une expression est plus clairement énoncée une jointure externe droite.

Mais l’un peut toujours être transformé en l’autre, et l’optimiseur fera aussi bien l’un que l’autre.

Pendant longtemps, au moins un des principaux produits rdbms ne supportait que LEFT OUTER JOIN. (Je crois que c'était MySQL.)

2
dkretz
SELECT * FROM table_a
INNER JOIN table_b ON ....
RIGHT JOIN table_c ON ....

Sinon, comment pourriez-vous rapidement/facilement rejoindre les 2 premières tables et rejoindre table_c tout en vous assurant que toutes les lignes de table_c sont toujours sélectionnées?

2
Matt

Dans certaines bases de données SQL, des indicateurs d'optimisation indiquent à l'optimiseur de joindre les tables dans l'ordre dans lequel elles apparaissent dans la clause FROM - par exemple. /*+ORDERED */ dans Oracle. Dans certaines mises en œuvre simples, il peut même s'agir du seul plan d'exécution disponible.

Dans de tels cas, l'ordre des tables dans la clause FROM est important, donc RIGHT JOIN peut être utile. 

1
Jiri Tousek

Je pense que c'est difficile si vous n'avez pas le droit de rejoindre dans ce cas. ex avec Oracle.

with a as(
     select 1 id, 'a' name from dual union all
     select 2 id, 'b' name from dual union all
     select 3 id, 'c' name from dual union all
     select 4 id, 'd' name from dual union all
     select 5 id, 'e' name from dual union all
     select 6 id, 'f' name from dual 
), bx as(
   select 1 id, 'fa' f from dual union all
   select 3 id, 'fb' f from dual union all
   select 6 id, 'f' f from dual union all
   select 6 id, 'fc' f from dual 
)
select a.*, b.f, x.f
from a left join bx b on a.id = b.id
right join bx x on a.id = x.id
order by a.id
0
Hong Van Vit