Opérateur Oracle «(+)»

155

Je vérifie quelques anciennes instructions SQL dans le but de les documenter et probablement de les améliorer.

Le SGBD est Oracle

Je n'ai pas compris une déclaration qui se lisait comme ceci:

select ...
from a,b
where a.id=b.id(+)

Je suis confus au sujet de l' (+)opérateur, et je n'ai pu l'obtenir sur aucun forum ... (la recherche de + entre guillemets ne fonctionnait pas non plus).

Quoi qu'il en soit, j'ai utilisé 'Explain Plan' de SQLDeveloper et j'ai obtenu une sortie disant cela HASH JOIN, RIGHT OUTER, etc.

Y aurait-il une différence si je supprimais l' (+)opérateur à la fin de la requête? La base de données doit-elle satisfaire certaines conditions (comme avoir des index, etc.) avant de (+)pouvoir être utilisée? Il serait très utile que vous puissiez me fournir une compréhension simple, ou quelques bons liens où je peux lire à ce sujet.

Merci!

Sekhar
la source
1
Ce n'est pas un opérateur. C'est juste un morceau de syntaxe qui affecte ce que fait JOIN.
philipxy

Réponses:

187

Il s'agit d'une notation spécifique à Oracle pour une jointure externe, car le format ANSI-89 (utilisant une virgule dans la clause FROM pour séparer les références de table) ne standardisait pas les jointures externes.

La requête serait réécrite dans la syntaxe ANSI-92 comme suit:

   SELECT ...
     FROM a
LEFT JOIN b ON b.id = a.id

Ce lien est assez bon pour expliquer la différence entre les JOIN .


Il convient également de noter que même si cela (+)fonctionne, Oracle recommande de ne pas l' utiliser :

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

Poneys OMG
la source
79
Exactement raison. Afin de garder le (+) droit dans ma tête (côté gauche contre côté droit), j'aime penser au (+) comme "l'ajout de valeurs NULL si aucune correspondance n'est trouvée". Par exemple, "a.id = b.id (+)" signifie autoriser b.id à être NULL s'il n'y a pas de correspondance avec a.id.
plage
merci ... je suppose que l'ajout de la clause from devrait donner le même résultat !!
Kiran S
Vous voudrez peut-être avoir un lien vers la documentation officielle d'Oracle: docs.oracle.com/html/A95915_01/sqopr.htm
Vargan
27

L'opérateur (+) indique une jointure externe. Cela signifie qu'Oracle retournera toujours les enregistrements de l'autre côté de la jointure même en l'absence de correspondance. Par exemple, si a et b sont emp et dept et que vous pouvez avoir des employés non affectés à un service, l'instruction suivante renverra les détails de tous les employés, qu'ils aient ou non été affectés à un service.

select * from emp, dept where emp.dept_id=dept.dept_id(+)

Donc, en bref, la suppression du (+) peut faire une différence significative, mais vous pourriez ne pas le remarquer pendant un certain temps en fonction de vos données!

Hot-dog
la source
25

Dans Oracle, (+) désigne la table "facultative" dans la jointure. Donc dans votre requête,

SELECT a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id(+)

c'est une JOINTURE EXTERNE GAUCHE de la table 'b' à la table 'a'. Il renverra toutes les données de la table 'a' sans perdre ses données lorsque l'autre côté (table optionnelle 'b') n'a pas de données.

Schéma de la jointure externe gauche

La syntaxe standard moderne pour la même requête serait

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b ON a.id=b.id

ou avec un raccourci pour a.id=b.id(non pris en charge par toutes les bases de données):

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b USING(id)

Si vous supprimez (+), ce sera une requête de jointure interne normale

Syntaxe plus ancienne, à la fois dans Oracle et dans d'autres bases de données:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id

Syntaxe plus moderne:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
INNER JOIN b ON a.id=b.id

Ou simplement:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
JOIN b ON a.id=b.id

Diagramme de jointure intérieure

Il ne retournera que toutes les données où la valeur 'id' des tables 'a' et 'b' est la même, signifie partie commune.

Si vous souhaitez faire de votre requête une jointure droite

C'est exactement la même chose qu'un LEFT JOIN, mais change quelle table est facultative.

Schéma de la jonction externe droite

Ancienne syntaxe Oracle:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id(+)=b.id

Syntaxe standard moderne:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
RIGHT JOIN b ON a.id=b.id

Réf et aide:

https://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:6585774577187

Jointure externe gauche à l'aide de la connexion + à Oracle 11g

https://www.w3schools.com/sql/sql_join_left.asp

Md. Salman Fahad célèbre
la source
Les étiquettes de cercle "table1" et "table2" n'ont aucun sens. La signification la plus simple des éléments de cercle est celle des lignes de sortie. Ensuite, le croissant de gauche contient les lignes étendues nulles de table1 et le croissant droit contient les lignes étendues nulles de table2. Les autres significations des cercles sont obscures. Que pensez-vous exactement des diagrammes? Pourquoi les avez-vous mis autrement qu'en copiant aveuglément les (mauvaises) présentations d'autres personnes?
philipxy
Vous avez maintenant étiqueté les cercles a et b. Les cercles ne sont pas des rangées de a et b. Les cercles gauche et droit pourraient raisonnablement être étiquetés comme des lignes d'une jointure gauche b et d'une jointure droite b. De plus, vous ne décrivez pas ce que sont ces lignes encerclées en termes d'entrée. Déterminez par vous-même ce qu'il y a dans les cercles. Si vous allez coller les étiquettes a et b sur les cercles, expliquez clairement avec des mots ce que chaque étiquette a à voir avec son cercle. (Il n'y a pas de raison simple de les étiqueter a et b.) Il est bon que vous ayez correctement étiqueté les zones vertes.
philipxy
6

En pratique, le symbole + est placé directement dans l'instruction conditionnelle et sur le côté de la table optionnelle (celle qui est autorisée à contenir des valeurs vides ou nulles dans le conditionnel).

ensoleillé
la source
Le (+) est placé immédiatement à droite d'un nom de colonne. Cette réponse n'est pas claire à ce sujet. Que signifie «en pratique»? (Rhétorique.) (Et vous ne voulez probablement pas dire «déclaration».)
philipxy