Inicio‎ > ‎SQL‎ > ‎Lliçons SQL‎ > ‎

T07 Conjunts

Operacions de conjunts i MySQL

Un operador sobre conjunts combina el resultat de dues sentències select en un únic resultat. Depenent del tipus d’operació aquestes sentències hauran de complir uns requisits en quant al resultat que donen.

Els operadors de conjunts definits per a l’àlgebra relacional, base sobre la qual se cimenta SQL, són la unió, intersecció, diferència, producte cartesià i divisió. En altres motors de base de dades es disposa d’alguns operadors com UNIÓ, INTERSECT i MINUS.

En MySQL només està disponible l’operador UNION, encara que l’operativa dels altres pot simular-se amb altres operadors de què ja hem vist uns quants.

Unió

En utilitzar l’operador UNIÓ entre dues sentències select, el resultat final estarà compost per totes aquelles files que apareixen en el resultat de com a mínim una de les select. L’operador UNION elimina files duplicades en el resultat final. L’operador UNION ALL opera de la mateixa manera que l’operador UNION, però no elimina files duplicades en el resultat final.

Suposem que volem saber el nom dels professors que són ASO6 o imparteixen assignatures de 6 crèdits. Vegem primer el resultat de cada consulta per separat.

          1) Noms dels professors que tenen categoria ASO6.

select nombre from profesores where categoria='ASO6';


2) Noms dels professors que imparteixen assignatures de 6 crèdits.

select nombre
from profesores p, imparte i, asignaturas
where p.dni=i.dni and asignatura=codigo and creditos=6;




Noms dels professors que són ASO6 o imparteixen assignatures de 6 crèdits.

select nombre from profesores where categoria='ASO6'
UNION
select nombre
from profesores p, imparte i, asignaturas
where p.dni=i.dni and asignatura=codigo and creditos=6;

nombre
RAFAEL ROMERO
EVA GOMEZ



La mateixa consulta però solucionada amb UNION ALL

select nombre from profesores where categoria='ASO6'
UNION ALL
select nombre
from profesores p, imparte i, asignaturas
where p.dni=i.dni and asignatura=codigo and creditos=6;

nombre
RAFAEL ROMERO
EVA GOMEZ
EVA GOMEZ
RAFAEL ROMERO


Intersecció

Encara que no hi ha tal operador en MySQL, normalment es pot substituir per consultes ja conegudes.

DNI dels professors que imparteixen i preparen.

IMPARTE[dni]

(COORDINADORES[dni])

El que hauria de solucionar-se com

select dni from imparte
INTERSECT
select dni from prepara;

en realitat, en MySQL, hem d’expressar-ho com:

select distinct i.dni
from imparte i, prepara pp
where pp.dni=i.dni;

dni
21111222
21333444

És important l’ús de modificador distinct per a que l’expressió estiga substituint efectivament l’operativa de la intersecció: les operacions de conjunts no tornen duplicats (unió all és una extensió perquè es puguen resoldre un cert tipus de consultes que sí que necessiten els duplicats)



Diferència

L’operador MINUS tampoc està implementat en MySQL però és fàcilment substituïble per expressions NOT IN. En tot cas, el resultat final estarà compost només per aquelles files que apareixen en el resultat de la primera select i no apareixen en el resultat de la segona.


DNI i nom dels professors que són TEU i no imparteixen assignatures de 6 crèdits.

PROFESORES donde categoría='TEU' [dni,nombre]

-

(PROFESORES x IMPARTE x ASIGNATURA
donde (PROFESORES.dni = IMPARTE.dni y codigo=asignatura y créditos=6)
[PROFESORES.dni,nombre])

El que hauria de solucionar-se com

select dni,nombre from profesores where categoria='TEU'
MINUS

select p.dni,nombre

from profesores p, imparte i, asignaturas

where p.dni=i.dni and asignatura=codigo and creditos=6;


ha de solucionar-se com

select dni,nombre from profesores where categoria='TEU'
and dni NOT IN 
(select p.dni
 from profesores p, imparte i, asignaturas
 where p.dni=i.dni and asignatura=codigo and creditos=6);

dni nombre
21222333 MANUEL PALOMAR


Òbviament, podem simplificar la consulta:

select dni,nombre from profesores
where categoria='TEU'

  and dni NOT IN
(select dni
 from imparte i, asignaturas
 where asignatura=codigo and creditos=6);


Producte cartesià

En SQL, i com ja s’ha dit anteriorment, el producte cartesià es realitza amb una select "sense where".

select dni, codigo
from profesores, asignaturas

dni codigo
21111222 DGBD
21222333 DGBD
21333444 DGBD
21111222 FBD
21222333 FBD
21333444 FBD
21111222 FP
21222333 FP
21333444 FP
21111222 HI
21222333 HI
21333444 HI
21111222 PC
21222333 PC
21333444 PC

No obstant, el producte cartesià, com qualsevol un altre tipus de consulta, pot filtrar les files resultat a la nostra conveniència.

Dni dels professors que imparteixen 2 o més assignatures

select distinct i1.dni
from imparte i1, imparte i2
where i1.dni = i2.dni
    and i1.asignatura != i2.asignatura;

Del producte cartesià d’una taula per si mateixa només ens interessen les files en què el professor "de l’esquerra" és el mateix que el "de la dreta"; sí, a més, les assignatures són diferents, la conclusió no pot ser una altra que aquest professor compleix amb la condició.

Encara que per a l’exemple que hem proposat hi ha una forma més amigable de solucionar aquest enunciat, la que mostrem a continuació, el producte cartesià és una opció que podem utilitzar quan creguem convenient

select dni from imparte group by dni having count(*) >= 2;


Concatenació natural

Aquest operador està implementat en MySQL i Oracle Database però no és segur que altres SGBD el tinguen implementat igualment. Igual que en àlgebra relacional, aquest operador assumeix que hi ha columnes comunes en dues taules diferents (en principi, que s’anomenen igual) i automatitza la reunió (join) basant-se en la igualtat de valors en aquestes columnes comunes. És a dir:

Totes les dades de professors que imparteixen alguna assignatura i codis d'aquestes assignatures.

select p.dni, p.nombre, p.categoria, p.ingreso, i.asignatura
from profesores p, imparte i
where p.dni=i.dni;

obté el mateix resultat que 

select * from profesores NATURAL JOIN imparte;


En ambdós casos l’eixida és la que es mostra a continuació. Note’s que només es mostra una columna de "dni" (concretament la de PROFESORES, la taula a l’esquerra de l’operador).

dni nombre categoria ingreso asignatura
21111222 EVA GOMEZ TEU 1993-10-01 DGBD
21111222 EVA GOMEZ TEU 1993-10-01 FBD
21333444 RAFAEL ROMERO ASO6 1992-06-16 PC


L'expressió en àlgebra relacional seria:

PROFESORES ∞ IMPARTE

A pesar de la possible comoditat d’ús d’aquest operador cal tenir molta atenció, si no hi ha columnes comunes es tornarà un producte cartesià. Una altra font de resultats no esperats és que hi haja més columnes amb idèntic nom de les desitjades.

Material addicional

Encara que és un operador que es comporta de manera diferent als anteriors també podríem incloure EXISTS dins de la categoria d'operadors SQL de conjunts. A més, és la base a una de les simulacions clàssiques de l'operador DIVISIÓ de l'àlgebra relacional. Ambdós es comenten en una lliçó complementària.


Subpáginas (1): Conjunts 2