84 votes

Jointure externe gauche utilisant le signe + dans Oracle 11g

Quelqu'un peut-il me dire si les deux requêtes ci-dessous sont un exemple de jointure externe gauche ou de jointure externe droite ?

Table Part:
Name         Null?       Type
PART_ID      NOT NULL    VARCHAR2(4)
SUPPLIER_ID              VARCHAR2(4)

PART_ID SUPPLIER_ID
P1      S1
P2      S2
P3  
P4  

Table Supplier:
Name            Null?     Type
SUPPLIER_ID NOT NULL      VARCHAR2(4)
SUPPLIER_NAME   NOT NULL  VARCHAR2(20)

SUPPLIER_ID  SUPPLIER_NAME
S1           Supplier#1
S2           Supplier#2
S3           Supplier#3

Affichez toutes les pièces, qu'elles soient fournies par un fournisseur ou non :

SELECT P.Part\_Id, S.Supplier\_Name
FROM Part P, Supplier S
WHERE P.Supplier\_Id = S.Supplier\_Id (+)

SELECT P.Part\_Id, S.Supplier\_Name
FROM Part P, Supplier S
WHERE S.Supplier\_Id (+) = P.Supplier\_Id

29 votes

Vous devez éviter d'utiliser la notation '(+)' et mettre à jour les requêtes pour utiliser des jointures explicites.

3 votes

@JonathanLeffler 100% d'accord. Le problème est que je travaille avec des personnes qui ne veulent pas passer à la notation standard. J'écris de nouvelles requêtes avec la notation standard, mais je serai prêt à tirer dans une minute si une ancienne requête est modifiée.

3 votes

@JonathanLeffler Je suis d'accord, sauf si vous utilisez Oracle. Oracle, tel qu'il est actuellement, ne gère pas la syntaxe ansi aussi bien que l'opérateur (+) en interne. Bien qu'ils recommandent d'utiliser la syntaxe ansi :) docs.oracle.com/cd/B28359_01/server.111/b28286/queries006.ht‌​m

197voto

Wiseguy Points 9441

TableA LEFT OUTER JOIN TableB est équivalent à TableB RIGHT OUTER JOIN Table A .

Dans Oracle, (+) désigne la table "facultative" dans le JOIN. Ainsi, dans votre première requête, c'est un P LEFT OUTER JOIN S . Dans votre deuxième requête, c'est S RIGHT OUTER JOIN P . Ils sont fonctionnellement équivalents.

Dans la terminologie, RIGHT ou LEFT spécifie quel côté de la jointure a toujours un enregistrement, et l'autre côté peut être nul. Ainsi, dans un P LEFT OUTER JOIN S , P aura toujours un enregistrement parce qu'elle est sur le LEFT mais S pourrait être nulle.

Ver cet exemple de java2s.com pour des explications supplémentaires.


Pour clarifier, je suppose que je dis que la terminologie n'a pas d'importance, car elle n'est là que pour aider à visualiser. Ce qui compte, c'est que vous compreniez le concept de son fonctionnement.


DROITE contre GAUCHE

J'ai constaté une certaine confusion quant à ce qui compte pour déterminer la DROITE ou la GAUCHE dans la syntaxe de jointure implicite.

JOINTURE EXTERNE GAUCHE

SELECT *
FROM A, B
WHERE A.column = B.column(+)

JOINTURE EXTERNE DROITE

SELECT *
FROM A, B
WHERE B.column(+) = A.column

Je n'ai fait que permuter les côtés des termes dans la clause WHERE, mais ils sont toujours fonctionnellement équivalents. (Voir plus haut dans ma réponse pour plus d'informations à ce sujet). (+) détermine la DROITE ou la GAUCHE. (Plus précisément, si l'option (+) est à droite, c'est un LEFT JOIN. Si (+) est à gauche, c'est un JOINT DROIT).


Types de JOIN

Les deux styles de JOIN sont JOINs implicites y JOINs explicites . Il s'agit de styles différents d'écriture des JOIN, mais ils sont fonctionnellement équivalents.

Ver cette question SO .

JOINs implicites répertorie simplement toutes les tables ensemble. Les conditions de jointure sont spécifiées dans une clause WHERE.

JOIN implicite

SELECT *
FROM A, B
WHERE A.column = B.column(+)

JOINs explicites associer les conditions de jointure à l'inclusion d'une table spécifique plutôt que dans une clause WHERE.

JOIN explicite

SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column

Ces Les JOIN implicites peuvent être plus difficiles à lire et à comprendre, et ils présentent également quelques limitations puisque les conditions de jointure sont mélangées à d'autres conditions WHERE. À ce titre, les JOIN implicites sont généralement déconseillés en faveur de la syntaxe explicite.

0 votes

Pourriez-vous ajouter des exemples pour les cas non explicites FROM A, B situations ? Disons que, dans FROM A, B WHERE a.x = b.x (+) y FROM A, B WHERE b.x (+) = a.x La première est une jointure droite et la seconde une jointure gauche dans votre terminologie (en raison de l'emplacement du +), ou bien sont-elles toutes deux des jointures droites parce que le + se trouve à l'endroit où se trouve le +. B est sur la droite ?

0 votes

@Kerrek SB Ceux de la question originale le sont, tout comme ceux du lien dans ma réponse ci-dessus. Vous en voulez d'autres ?

3 votes

Bon, je comprends maintenant -- le JOIN est créé implicitement par la présence du (+). Cool.

9voto

Rahul Points 17363

Ces deux requêtes fonctionnent OUTER JOIN . Voir ci-dessous

Oracle vous recommande d'utiliser la syntaxe FROM clause OUTER JOIN plutôt que l'opérateur de jointure d'Oracle. Les requêtes de jointure externe qui utilisent l'opérateur l'opérateur de jointure Oracle (+) sont soumises aux règles et restrictions suivantes règles et restrictions suivantes, qui ne s'appliquent pas à la clause FROM OUTER JOIN syntaxe :

  • Vous ne pouvez pas spécifier l'opérateur (+) dans un bloc de requête qui contient aussi contient également la syntaxe de jointure de la clause FROM.

  • L'opérateur (+) ne peut apparaître que dans la clause WHERE ou, dans le contexte de la corrélation à gauche (lorsque l'on spécifie TAB). contexte de corrélation à gauche (lors de la spécification de la clause TABLE) dans la clause FROM. FROM, et ne peut être appliqué qu'à une colonne d'une table ou d'une vue.

  • Si A et B sont joints par des conditions de jointure multiples, vous devez utiliser l'opérateur (+) dans toutes ces conditions. Si vous ne le faites pas, alors Oracle retournera uniquement les lignes résultant d'une jointure simple, mais sans simple, mais sans avertissement ni erreur pour vous avertir que vous n'avez pas les résultats d'une jointure externe. que vous ne disposez pas des résultats d'une jointure externe.

  • L'opérateur (+) ne produit pas de jointure externe si vous spécifiez une table table dans la requête externe et l'autre table dans une requête interne.

  • Vous ne pouvez pas utiliser l'opérateur (+) pour joindre extérieurement une table à elle-même, bien que les auto-jointures soient valides. Par exemple, l'instruction suivante n'est pas valide :

    -- The following statement is not valid:
    SELECT employee_id, manager_id
       FROM employees
       WHERE employees.manager_id(+) = employees.employee_id;

    Cependant, l'auto-jonction suivante est valable :

    SELECT e1.employee_id, e1.manager_id, e2.employee_id
       FROM employees e1, employees e2
       WHERE e1.manager_id(+) = e2.employee_id
       ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
  • L'opérateur (+) ne peut être appliqué qu'à une colonne, et non à une expression arbitraire. arbitraire. Toutefois, une expression arbitraire peut contenir une ou plusieurs plusieurs colonnes marquées par l'opérateur (+).

  • Une condition WHERE contenant l'opérateur (+) ne peut pas être combinée avec une autre condition utilisant l'opérateur logique OR.

  • Une condition WHERE ne peut pas utiliser la condition de comparaison IN pour comparer une colonne marquée par l'opérateur (+) à une expression. colonne marquée par l'opérateur (+) avec une expression.

Si la clause WHERE contient une condition qui compare une colonne de la table B à une constante, l'opérateur (+) doit être appliqué à la condition. du tableau B avec une constante, l'opérateur (+) doit être appliqué à la clause colonne pour qu'Oracle renvoie les lignes de la table A pour lesquelles il a généré des nuls pour cette colonne. généré des valeurs nulles pour cette colonne. Sinon, Oracle renvoie uniquement les résultats d'une jointure simple.

Dans une requête qui effectue des jointures externes de plus de deux paires de tables, une seule table peut être la table générée nulle pour une seule autre table. table. Pour cette raison, vous ne pouvez pas appliquer l'opérateur (+) aux colonnes de B dans la condition de jointure de A et B et dans la condition de jointure de B et C. Reportez-vous à SELECT pour plus d'informations sur les conditions de jointure. et C. Reportez-vous à la section SELECT pour connaître la syntaxe d'une jointure externe.

Tiré de http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm

4voto

Charles Points 67

J'ai vu quelques contradictions dans les réponses ci-dessus, je viens d'essayer ce qui suit sur Oracle 12c et ce qui suit est correct :

JOINTURE EXTERNE GAUCHE

SELECT *
FROM A, B
WHERE A.column = B.column(+)

JOINTURE EXTERNE DROITE

SELECT *
FROM A, B
WHERE B.column(+) = A.column

1voto

Rupasa Sushma Points 85

JOINTURE EXTERNE GAUCHE

SELECT * FROM A, B WHERE A.column = B.column(+)

JOINTURE EXTERNE DROITE

SELECT * FROM A, B WHERE A.column (+)= B.column

0voto

Ramakrishna Talla Points 131
You can see answers from previous posts
However I added little more information 
    create table r2020 (id int, name varchar2(50),rank number);
    insert into r2020 values (101,'Rob Rama',1);
    insert into r2020 values (102,'Ken Krishna',3);
    insert into r2020 values (108,'Ray Rama',2);
    insert into r2020 values (109,'Kat Krishna',4);

    create table r2021 (id int, name varchar2(50),rank number);
    insert into r2021 values (102,'Ken Krishna',1); 
    insert into r2021 values (103,'Tom Talla',2);
    insert into r2021 values (108,'Ray Rama',2); 

    --LEFT OUTER JOIN  
        --oracle notation
        select * from r2020 r1, r2021 r2
        where  r1.id  = r2.id (+) 
        order by r1.id;

        --ANSI notation
        select * from r2020 r1
        left outer join r2021 r2 on  r1.id = r2.id  
        order by r1.id;
        --OUT PUT
        NAME        ID RANK  NAME_1     ID_1    RANK_1
        ----        -- ---- ----        ----   ------
        Rob Rama    101 1   (null)      (null)  (null)
        Ken Krishna 102 3   Ken Krishna 102     1
        Ray Rama    108 2   Ray Rama    108     2
        Kat Krishna 109 4   (null)      (null)  (null)

    --RIGHT OUTER JOIN  
        --oracle notation
        select * from r2020 r1, r2021 r2
        where  r1.id (+)  = r2.id 
        order by r1.id;

        --ANSI notation
        select * from r2020 r1
        right outer join r2021 r2 on  r1.id = r2.id  
        order by r1.id;
        --OUT PUT
        NAME        ID    RANK    NAME_1      ID_1    RANK_1
        ----        --    ----    ----        ----   ------
        Ken Krishna 102     3     Ken Krishna 102    1
        Ray Rama    108     2     Ray Rama    108    2
        (null)      (null) (null) Tom Talla   103    2

    --<b>MULTIPLE COLUMNS IN JOIN CONDITION</b>
    --LEFT OUTER JOIN  
        --oracle notation
        select * from r2020 r1, r2021 r2
        where  r1.id  = r2.id (+) and 
               r1.rank  = r2.rank (+)
        order by r1.id;

        --ANSI notation
        select * from r2020 r1
        left outer join r2021 r2 on  r1.id = r2.id and 
                                     r1.rank  = r2.rank 
        order by r1.id;
        --OUT PUT
        NAME        ID RANK  NAME_1     ID_1    RANK_1
        ----        -- ---- ----        ----   ------
        Rob Rama    101 1   (null)      (null)  (null)
        Ken Krishna 102 3   (null)      (null)  (null)
        Ray Rama    108 2   Ray Rama    108     2
        Kat Krishna 109 4   (null)      (null)  (null)

    --RIGHT OUTER JOIN  
        --oracle notation
        select * from r2020 r1, r2021 r2
        where  r1.id (+)  = r2.id and
               r1.rank(+)  = r2.rank 
        order by r1.id;

        --ANSI notation
        select * from r2020 r1
        right outer join r2021 r2 on  r1.id = r2.id and
                                      r1.rank  = r2.rank 
        order by r1.id;
        --OUT PUT
        NAME      ID     RANK   NAME_1       ID_1  RANK_1
        ----      --     ----   ----         ----  ------
        (null)    (null) (null) Ken Krishna  102   1
        Ray Rama  108     2     Ray Rama     108   2
        (null)    (null) (null) Tom Talla    103   2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X