Variants de JOIN

Índex

 

Insuficiència del JOIN simple

Tornem a l'exemple del personal d'una empresa, on havíem deixat sense explicació el fet que alguns regsitres quedaven desvinculats. Passa que en la darrera reunió de l'alta direcció es va decidir crear un departament nou, 'Exterior', i al mateix temps es va acordar contractar tres empleats nous: en un moment determinat - just quan figura que es va elaborar la taula - tenim un departament sense personal i 3 treballadors sense departament.

Podem pensar que aquesta és una situació excepcional. Res més lluny de la realitat: gairebé sempre el manteniment d'una base de dades és una feina digna de Sísif: un co la pedra és prop del cim, rodola cap avall. La feina, doncs, no s'acaba mai.: les bases de dades sobre realitats dinàmiques són inestables per naturalesa, i només es poden fixar d'una forma convencional i posant-hi data i hora.

Traduït a taules i registres, això significa que tothora hi ha dades insegures i vincles entre taules que fallen, i que per tant el JOIN tal com l'hem descrit és notòriament insuficient.

Ens cal doncs un recurs còmode i ràpid que ens ajudi en la gestió d'una base de dades perpètuament a mig fer. I aquest és el paper que els toca fer a les variants de JOIN.

 

INNER JOIN, LEFT JOIN I RIGHT JOIN

El JOIN vist fins ara té, com a nom complet, INNER JOIN, tot i que, com ja hem fet, es pot abreujar en JOIN. Presenta exclusivament els casos en què es compleix estrictament la condició expressada, i per tant no ens informa sobre els registres desaparellats si n'hi ha (treballadors sense departament, departaments sense treballadors...). Hi ha d'altres variants, LEFT OUTER JOIN, RIGHT OUTER JOIN i FULL OUTER JOIN (en aquestes tres es pot ometre el terme OUTER) , que mostren, a més, el contingut sencer d'una taula, o de l'altra, o de totes dues, com ho mostra el gràfic:

captura

LEFT i RIGHT es refereix a la posició relativa de les taules a partir del FROM.

Un cop més farem servir les taules de "Departaments" i de "Personal":

#

#

Recordem que aplicant el JOIN simple (explícit o implícit) no ens apareixien els treballadors nous ni el departament nou. Ara aplicarem el LEFT JOIN:

SELECT "Departaments"."Departament", "Personal"."Nom", "Personal"."Cognoms"
FROM "Personal"
LEFT JOIN "Departaments" ON "Personal"."IdD" = "Departaments"."IdD"
ORDER BY "Departaments"."Departament", "Personal"."Cognoms"

obtenim aquest resultat:

captura

Ara hi han aparegut tots els registres de la taula LEFT, i per tant també els treballadors nous, però no el departament nou.

I amb la versió RIGHT JOIN,

SELECT "Departaments"."Departament", "Personal"."Nom", "Personal"."Cognoms"
FROM "Personal"
RIGHT JOIN "Departaments" ON "Personal"."IdD" = "Departaments"."IdD"
ORDER BY "Departaments"."Departament", "Personal"."Cognoms"

obtenim aquest resultat:

captura

Ara hi han aparegut tots els registres de la taula RIGHT, i per tant també el departament nou, però no els treballadors nous.

Notem que les posicions LEFT i RIGHT són arbitràries; aquesta segona recerca s'hauria pogut fer intercanviant la posició de les taules i fent servir LEFT JOIN:

SELECT "Departaments"."Departament", "Personal"."Nom", "Personal"."Cognoms"
FROM "Departaments"
LEFT JOIN "Personal" ON "Personal"."IdD" = "Departaments"."IdD"
ORDER BY "Departaments"."Departament", "Personal"."Cognoms"

El resultat seria idèntic.

 

FULL OUTER JOIN

Amb el FULL OUTER JOIN obtenim la presentació conjunta de tots els registres de totes dues taules, tant si estan aparellats com si no ho estan.

És igual que els anteriors, substituint LEFT i RIGHT per FULL. Alguns programes, però, no accepen aquesta sentència.

Una alternativa és fer un LEFT JOIN seguit d'un RIGHT JOIN i unir-los amb UNION:

SELECT "Departaments"."Departament", "Personal"."Nom", "Personal"."Cognoms", "Personal"."Antiguitat"
FROM "Personal"
LEFT JOIN "Departaments" ON "Personal"."IdD" = "Departaments"."IdD"
UNION
SELECT "Departaments"."Departament", "Personal"."Nom", "Personal"."Cognoms", "Personal"."Antiguitat"
FROM "Personal"
RIGHT JOIN "Departaments" ON "Personal"."IdD" = "Departaments"."IdD"
ORDER BY "Departament","Cognoms"

El resultat (obtingut amb Access 2003) és el següent:

captura

 

CROSS JOIN i producte cartesià

S'anomena producte cartesià el conjunt format pels aparellaments de tots els elements d'un conjunt amb tots els elements d'un altre conjunt.

El producte cartesià es pot obtenir amb el comandament CROSS JOIN:

...
FROM "Taula_1"
CROSS JOIN "Taula_2"
...

Suposem un conjunt de "Nois" i un conjunt de "Noies", reunits en una sessió de ball heterosexual i per parelles; són els que consten en les taules següents:

captura

El producte cartesià d'aquests dos conjunts és el conjunt de totes les parelles de ball possibles (no de les que realment s'arribin a produir, que en serà un subconjunt!)

El CROSS JOIN no funciona en alguns programes; però podem subtituir-lo fàcilment aplicant a les dues taules un JOIN implícit sense clàusula WHERE:

...
SELECT *
FROM "Nois", "Noies"
...

amb el resultat següent:

captura

El producte cartesià té importància teòrica perquè podem considerar que des del punt de vista lògic qualsevol subconjunt JOIN consisteix a delimitar el CROSS JOIN amb alguna condició afegida.