Professional Documents
Culture Documents
INGENIERA EN SISTEMAS
DE INFORMACIN
GESTIN DE DATOS
APUNTES TERICOS
Unidad 6: SQL
Profesor Teora: Ing. Carolina Orcola
Jefe de T. P.: Ing. Luis Eiman
Auxiliar de T.P.: Juan Carlos Fernandez
ndice
Unidad VI: SQL ............................................................................................................................... 3
Introduccin ................................................................................................................................ 3
Formas de las consultas SQL Bsicas ........................................................................................ 4
Ejemplos de consultas bsicas de SQL................................................................................... 7
Expresiones y cadenas de caracteres en la orden SELECT..................................................... 8
Subconsultas o Consultas Anidadas ........................................................................................... 9
Otros predicados ......................................................................................................................... 9
UNION, INTERSECT y EXCEPT .............................................................................................. 11
Consultas Anidadas .................................................................................................................. 15
Consultas anidadas correlacionadas ..................................................................................... 15
Ms ejemplos de consultas anidadas .................................................................................... 16
Operadores de agregacin........................................................................................................ 17
Ordenacin de datos resultantes............................................................................................... 19
La clusula GROUP BY y HAVING ............................................................................................. 19
Ms ejemplos de consultas de agregacin ............................................................................ 20
Valores nulos ............................................................................................................................ 22
Comparaciones que emplean valores nulos .......................................................................... 22
Las conectivas lgicas AND, OR y NOT................................................................................ 22
Consecuencias para las estructuras de SQL ......................................................................... 23
Reuniones externas .............................................................................................................. 23
Desactivacin de valores nulos ............................................................................................. 23
JOINs o Reuniones ................................................................................................................... 24
Reunin interna - clusulas inner join / on ............................................................................. 24
Reunin externa - left outer join / right outer join ................................................................... 24
Que trae de nuevo SQL Server 2008? ....................................... Error! Marcador no definido.
Bibliografa .................................................................................................................................... 26
Ao 2010
Pgina 2
2006 SQL:2006
2008 SQL:2008
Comentarios
Primera publicacin hecha por ANSI. Confirmada por ISO en 1987.
Revisin menor.
Revisin mayor.
Se agregaron expresiones regulares, consultas recursivas (para relaciones
jerrquicas), triggers y algunas caractersticas orientadas a objetos.
Introduce algunas caractersticas de XML, cambios en las funciones,
estandarizacin del objeto sequence y de las columnas autonumericas. (Ver
Eisenberg et al.: SQL:2003 Has Been Published.)
ISO/IEC 9075-14:2006 Define las maneras en las cuales el SQL se puede utilizar
conjuntamente con XML. Define maneras importar y guardar datos XML en una
base de datos SQL, manipulndolos dentro de la base de datos y publicando el
XML y los datos SQL convencionales en forma XML. Adems, proporciona
facilidades que permiten a las aplicaciones integrar dentro de su cdigo SQL el uso
de XQuery, lenguaje de consulta XML publicado por el W3C (World Wide Web
Consortium) para acceso concurrente a datos ordinarios SQL y documentos XML.
Permite el uso de la clusula ORDER BY fuera de las definiciones de los cursores.
Incluye los disparadores del tipo INSTEAD OF. Aade la sentencia TRUNCATE.
Introduccin
El lenguaje SQL tiene varios aspectos diferentes:
Ao 2010
Pgina 3
Seguridad. SQL ofrece mecanismos para controlar el acceso de los usuarios a los objetos
de datos, como tablas y vistas.
Las consultas que se van a usar de ejemplo emplean las tablas ya usadas en la unidad anterior,
es decir:
Marineros (idm: integer, nombrem: string, categoria: integer, edad: real)
Barcos (idb: integer, nombreb: string, color: string)
Reservas (idm: integer, idb: integer, fecha: date)
Se usan los ejemplares M3 y R2 de Marineros y Reservas respectivamente.
M3
idm
22
29
31
32
58
64
71
74
85
95
B1
nombrem
Dominguez
Barvo
Lorca
Alndez
Rubio
Horacio
Zuazo
Horacio
Arturo
Benito
idb
101
102
103
104
nombreb
Intrpido
Intrpido
Campen
Mstico
categoria
7
1
8
8
10
7
10
9
3
3
edad
45,0
33,0
55,5
25,5
35,0
35,0
16,0
35,0
25,5
63,5
R2
idm
22
22
22
22
31
31
31
64
64
74
idb
101
102
103
104
102
103
104
101
102
103
fecha
10/10/2008
10/10/2008
10/8/2008
10/7/2008
11/10/2008
11/6/2008
11/12/2008
9/5/2008
9/8/2008
9/8/2008
color
azul
rojo
verde
rojo
Ao 2010
Pgina 4
nombrem
Dominguez
Barvo
Lorca
Alndez
Rubio
Horacio
Zuazo
Arturo
Benito
edad
45,0
33,0
55,5
25,5
35,0
35,0
16,0
35,0
25,5
63,5
edad
45,0
33,0
55,5
25,5
35,0
35,0
16,0
25,5
63,5
Respuesta a C15
La siguiente consulta es equivalente a una aplicacin del operador seleccin del lgebra
relacional.
(C11) Averiguar todos los marineros con categora superior a 7.
{ M | M Marineros M.categoria > 7} En Clculo Relacional de Tuplas
Ao 2010
Pgina 5
La palabra clave DISTINCT es opcional. Indica que la tabla calculada como respuesta a
la consulta no debe contener duplicados, es decir, dos copias de la misma fila. El valor
predeterminado es que los duplicados no se eliminan.
Aunque las reglas anteriores describen (de manera informal) la sintaxis de las consultas bsicas
de SQL, no indican el significado de las consultas. La respuesta de las consultas es en si misma
una relacin que es un multiconjunto de filas en SQL_ cuyo contenido se puede comprender
considerando la siguiente estrategia de evaluacin conceptual:
1. Calcular el producto cartesiano de las tablas de la lista-de-tablas.
2. Eliminar filas del producto cartesiano que no cumplan las condiciones de condicin.
3. Eliminar todas las columnas que no aparezcan en la lista-de-seleccin.
4. Si se especifica DISTINCT, eliminar las filas repetidas.
Esta sencilla estrategia de evaluacin conceptual explicita las filas que deben encontrarse en la
respuesta a la consulta. Sin embargo, es probable que sean bastante ineficiente.
(C1) Averiguar el nombre de los marineros que han reservado el barco 103
En lgebra relacional era:
En SQL es:
SELECT M.nombrem
FROM Marineros M, Reservas R
WHERE M.ide = R.ide AND R.ide = 103
Usamos para esta consulta los ejemplares R3 de reservas y M4 de Marineros (para hacer menos
tedioso el ejemplo).
M4 idm
nombrem
categoria
edad
R3 Idm
idb
fecha
22 Dominguez
7
45,0
22
101
10/10/2008
31 Lorca
8
55,5
58
103
11/12/2008
58 Rubio
10
35,0
El primer paso es crear el producto cartesiano de M4XR3, que podemos ver en la siguiente figura.
idm
22
22
31
31
58
58
Ing. Carolina Orcola
nombrem
Dominguez
Dominguez
Lorca
Lorca
Rubio
Rubio
categoria
7
7
8
8
10
10
Ao 2010
edad
45,0
45,0
55,5
55,5
35,0
35,0
Idm
22
58
22
58
22
58
idb
101
103
101
103
101
103
fecha
10/10/2008
11/12/2008
10/10/2008
11/12/2008
10/10/2008
11/12/2008
Pgina 6
El segundo paso es aplicar la condicin M.ide = R.ide AND R.ide = 103. Este paso elimina todas
las filas del ejemplar resultante del producto cartesiano visto antes menos la ltima.
idm
58
Nombrem
Rubio
categoria
10
edad
35,0
Idm
58
idb
103
fecha
11/12/2008
El tercer paso es eliminar las columnas no deseadas; solo aparece nombrem en la clusula
SELECT. Este paso deja entonces una sola columna y una sola fila, que es la siguiente:
nombrem
Rubio
Ejemplos de consultas bsicas de SQL
A continuacin se presentan varios ejemplos de consultas SQL, muchas de las cuales ya se
expresaron anteriormente en el lgebra relacional y el clculo relacional. El primer ejemplo ilustra
que el empleo de variables de rango es opcional, a menos que sea necesario para resolver alguna
ambigedad. La consulta C1, que ya se vi antes, tambin se puede expresar de la siguiente
manera:
SELECT nombrem
FROM Marineros M, Reservas R
WHERE M.ide = R.ide AND ide = 103
Slo hay que cualificar las apariciones de idm, ya que esta columna aparece en las dos tablas
vinculadas a la consulta. Otra manera equivalente de escribir esta consulta sera:
SELECT nombrem
FROM Marineros, Reservas
WHERE Marineros.ide = Reservas.ide AND R.ide = 103
Esta consulta muestra que los nombres de las tablas se pueden emplear de manera implcita
como variables de fila. Slo hace falta introducir variables de rango de manera explcita cuando la
clusula FROM contiene ms de una aparicin de una misma relacin. No obstante, se
recomienda el empleo explcito de las variables de rengo y la condicin completa de todas las
apariciones de las columnas con una variable de rango para mejorar la legibilidad de las
consultas.
(C16) Averiguar el idm de los marineros que han reservado barcos rojos.
SELECT R.idm
FROM Barcos B, Reservas R
WHERE B.idb = R.idb AND B.color = rojo
Esta consulta contiene una reunin de dos tablas, seguida de una seleccin del color de los
barcos. Se puede pensar en B y en R como en filas de las tablas correspondientes que prueban
que un marinero con idm = R.idm reserv un barco B.idb rojo.
(C2) Averiguar el nombre de los marineros que han reservado barcos rojos.
En lgebra relacional:
SELECT M.nombrem
FROM Marineros M, Reservas R, Barcos B
WHERE M.idm = R.idm AND R.idb = B.idb AND B.color = rojo
Esta consulta contiene una reunin de tres tablas seguida de una seleccin del color de los
barcos. La reunin con Marineros permite averiguar el nombre del marinero que, segn la tupla R
de Reservas, ha reservado el barco rojo descripto por la tupla B.
Ao 2010
Pgina 7
SELECT B.color
FROM Marineros M, Reservas R, Barcos B
WHERE M.idm = R.idm AND R.idb = B.idb AND M.nombre = Lpez
Esta consulta es muy parecida a la anterior. Obsrvese que, en general, puede que haya ms de
un marinero llamado Lpez (ya que nombrem no es clave de Marineros); esta consulta sigue
siendo correcta en el sentido que devolver el color de los barcos reservados por algn Lpez, si
es que hay varios marineros llamados Lpez.
(C4) Averiguar el nombre de los marineros que han reservado, como mnimo, un barco.
En lgebra relacional:
SELECT M.nombrem
FROM Marineros M, Reservas R
WHERE M.idm = R.idm
La reunin de Marineros y Reservas garantiza que, para cada nombrem seleccionado, el marinero
haya hecho alguna reserva. (Si algn marinero no ha hecho ninguna reserva, el segundo paso de
la estrategia de evaluacin conceptual eliminar todas las filas del producto cartesiano que
impliquen a ese marinero).
Expresiones y cadenas de caracteres en la orden SELECT
SQL soporta una versin ms general de la lista-de-seleccin que una mera lista de columnas.
Cada elemento de una lista-de-seleccin puede ser de la forma expresin AS nombre-columna,
donde expresin es cualquier expresin aritmtica o de cadena de caracteres para los nombres de
las columnas (posiblemente con variables de rango antepuestas) y constantes, y nombre-columna
es un nombre nuevo para esa columna en el resultado de la consulta.
Tambin puede contener agregados como sum y count, entre otros. La norma de SQL tambin
incluye expresiones para los valores de fecha y de hora, que no se tratarn. Aunque no forman
parte de la norma de SQL, muchas implementaciones soportan tambin el empleo de funciones
predefinidas como sqrt, sen y mod.
(C17) Calcular el incremento de la categora de las personas que han navegado en dos barcos
diferentes el mismo da.
Ao 2010
Pgina 8
ordenacin, u orden de colocacin, para los conjuntos de caracteres. La ordenacin permite que
el usuario especifique los caracteres que son menores que otros y ofrece gran flexibilidad para la
manipulacin de cadenas de caracteres.
Adems, SQL ofrece soporte para la comparacin de estructuras mediante el operador LIKE,
junto con el uso de los smbolos % (que sustituye a cero o ms caracteres arbitrarios) y _ (que
sustituye exactamente a un carcter arbitrario). As _AB% denota una estructura que coincida
con todas las cadenas de caracteres que contienen, como mnimo, tres caracteres, en las que el
segundo y tercer carcter son A y B respectivamente. Observemos que, a diferencia de los dems
operadores de comparacin, los espacios en blanco pueden resultar significativos para el
operador LIKE (dependiendo de la ordenacin del conjunto de caracteres subyacentes). Por lo
tanto, Jess=Jess es verdadero, mientras que Jess LIKE Jess es falso. Veamos un
ejemplo de LIKE.
(C18) Averiguar la edad de los marineros cuyo nombre comienza con B, acaba con O y tiene
como mnimo seis caracteres.
SELECT M.edad
FROM Marineros M
WHERE M.nombrem LIKE B_%_ _ _O
Subconsultas o Consultas Anidadas
Al escribir una consulta, a veces hay que expresar una condicin que hace referencia a alguna
tabla que, a su vez, se debe calcular. Las consultas empleadas para calcular esas tablas son
subconsultas y aparecen como parte de las consultas principales.
Una subconsulta es una consulta incluida en una clusula WHERE o HAVING(1) de otra consulta.
En algunas ocasiones, para expresar ciertas condiciones no hay ms remedio que obtener el valor
que buscamos como resultado de una consulta.
SELECT M.nombrem
FROM Marineros M
WHERE M.categoria = (SELECT MAX M.categoria
FROM Marineros M)
En este ejemplo, queremos ver los nombre de los marineros que tienen la categora mxima, y
para ello debemos primero averiguar cul es esa categora mxima (usamos la funcin de
agregacin MAX que veremos luego).
(1) La clusula HAVING la vemos despus.
Otros predicados
Predicado BETWEEN
Para expresar una condicin que quiere encontrar un valor entre unos lmites concretos podemos
usar el predicado BETWEEN.
SELECT columnas
FROM tabla
WHERE columna BETWEEN lmite1 AND lmite2
Por ejemplo, queremos ver los marineros cuyo rango de edad est entre 20 y 35 aos:
SELECT M.nombrem
FROM Marineros M
WHERE M.edad BETWEEN 20 AND 35
Ao 2010
Pgina 9
Predicado IN
Para comprobar si un elemento coincide con los elementos de una lista utilizaremos IN, y para
ver si no coinciden NOT IN.
SELECT columnas
FROM tabla
WHERE columna [NOT] IN (valor1 valorN)
Por ejemplo, queremos ver los marineros cuya edad sea 15, 20 y 30 aos:
SELECT M.nombrem
FROM Marineros M
WHERE M.edad IN (15, 20, 35)
Predicado IS
Para comprobar si un valor es nulo utilizamos IS NULL, y para averiguar si no es nulo, IS NOT
NULL. El formato es:
SELECT columnas
FROM tabla
WHERE columna IS [NOT] NULL
Como ejemplo, supongamos que la tabla Marineros tiene una columna ms hijos, en la que se
pone la cantidad de hijos que tiene. Bajo ese supuesto, se puede escribir la consulta pidiendo el
nombre de los marineros sin hijos, as:
SELECT M.nombrem
FROM Marineros M
WHERE M.hijos IS NULL
Predicado ALL o ANY/SOME
Para ver si una columna cumple con la condicin de que todas sus filas (ALL) o algunas de sus
filas (ANY/SOME) satisfaga una condicin, podemos escribir:
SELECT columnas
FROM tabla
WHERE columna operador_comparacin {ALL/ANY/SOME} subconsulta
Por ejemplo, escribimos una consulta que liste los idb de los barcos que fueron reservados por
marineros todos mayores de 18 aos:
SELECT R.idb
FROM Reserrvas R
WHERE R.idm = ALL SELECT M.idm
FROM Marineros M
WHERE M.edad>=18
Y para ejemplificar el uso de ANY/SOME, podemos pedir que liste los idb de los barcos que fueron
reservados por al menos un o algn marinero mayor de 18 aos:
SELECT R.idb
FROM Reserrvas R
WHERE R.idm = ANY SELECT M.idm
FROM Marineros M
WHERE M.edad>=18
Ing. Carolina Orcola
Ao 2010
Pgina 10
Predicado EXIST
Para comprobar si una consulta produce alguna fila de resultado, es decir, si existe un resultado,
podemos usar el predicado EXISTS. As mismo, para comprobar si no existe se aplicara NOT
EXISTS.
SELECT columnas
FROM tabla
WHERE [NOT] EXISTS subconsulta
Por ejemplo, para mostrar el idm y nombre de los marineros que reservaron un bote determinado
podemos tambin escribir:
SELECT columna
FROM tabla
[WHERE condiciones]
UNION [ALL]
SELECT columna
FROM tabla
[WHERE condiciones]
Si ponemos la opcin ALL, aparecern todas las filas obtenidas a causa de la unin. No la
pondremos si queremos eliminar las filas repetidas. Las tablas resultantes de las sentencias a unir
deben ser compatibles con la unin.
Consideremos la siguiente consulta:
(C5) Averiguar el nombre de los marineros que han reservado barcos rojos o verdes.
SELECT M.nombrem
FROM Marineros M, Reservas R, Barcos B
WHERE M.idm=R.idm AND R.idb=B.idb
AND (B.color=rojo OR B.color=verde)
Esta consulta se expresa fcilmente usando el operador OR en la clusula WHERE. Sin embargo,
la siguiente consulta, que es idntica salvo por el empleo de y en lugar de o resulta mucho ms
difcil:
(C6) Averiguar el nombre de los marineros que han reservado barcos rojos y verdes.
Ing. Carolina Orcola
Ao 2010
Pgina 11
SELECT M.nombrem
FROM Marineros M, Reservas R1, Barcos B1, Reservas R2, Barcos B2
WHERE M.idm=R1.idm AND R1.idb=B1.idb
AND M.idm=R2.idm AND R2.idb=B2.idb
AND B1.color=rojo AND B2.color=verde
Se puede pesnar en R1 y en B1 como en filas que prueban que el mariner M.idm ha reservado
barcos rojos; y de manera parecida, R2 y B2 prueban que el mismo marinero ha reservado
tambin barcos verdes. M.nombrem no se incluye en el resultado a menos que se encuentren
cinco filas como M, R1, B1, R2 y B2.
La consulta anterior es difcil de comprender (y tambin ineficiente de ejecutar). Una solucin ms
adecuada para estas dos consultas sera emplear UNION e INTERSECT.
As, la consulta C5 se puede escribir:
SELECT M.nombrem
FROM Marineros M, Reservas R, Barcos B
WHERE M.idm=R.idm AND R.idb=B.idb
AND B.color=rojo
UNION
SELECT M2.nombrem
FROM Marineros M2, Reservas R2, Barcos B2
WHERE M2.idm=R2.idm AND R2.idb=B2.idb
AND B2.color=verde
Esta consulta indica que se desea la unin del conjunto de marineros que han reservado barcos
rojos con el conjunto de marineros que han reservado barcos verdes.
En completa simetra, la consulta C6 se escribira:
SELECT M.nombrem
FROM Marineros M, Reservas R, Barcos B
WHERE M.idm=R.idm AND R.idb=B.idb
AND B.color=rojo
INTERSECT
SELECT M2.nombrem
FROM Marineros M2, Reservas R2, Barcos B2
WHERE M2.idm=R2.idm AND R2.idb=B2.idb
AND B2.color=verde
La clusula INTERSECT genera la interseccin entre dos o ms sentencias SELECT FROM. Su
formato es:
SELECT columna
FROM tabla
[WHERE condiciones]
INTERSECT [ALL]
SELECT columna
FROM tabla
Ing. Carolina Orcola
Ao 2010
Pgina 12
[WHERE condiciones]
Si ponemos la opcin ALL, aparecern todas las filas obtenidas a partir de la interseccin. No la
pondremos si queremos eliminar las filas repetidas.
Las tablas resultantes de las sentencias a unir deben ser compatibles con la unin.
Interseccin utilizando IN
SELECT columna
FROM tabla
WHERE columna IN ( SELECT columna
FROM tabla
[WHERE condiciones])
SELECT columna
FROM tabla
WHERE EXISTS (SELECT *
FROM tabla
WHERE condiciones)
Para hallar la diferencia entre dos o ms sentencias SELECT FROM podemos utilizar la clsula
EXCEPT, que tiene este formato:
SELECT columna
FROM tabla
[WHERE condiciones]
EXCEPT [ALL]
SELECT columna
FROM tabla
[WHERE condiciones]
Si ponemos la opcin ALL, aparecern todas las filas obtenidas a partir de la diferencia. No la
pondremos si queremos eliminar las filas repetidas.
Al igual que la interseccin y la unin, las relaciones que componen la diferencia deben ser
compatibles con la unin, o debemos forzar que las columnas a vincular lo sean.
La diferencia es, junto con la interseccin, una de las operaciones del SQL que se puede realizar
de ms formas diferentes. As es que podemos encontrar la diferencia usando en vez de EXCEPT
los predicados NOT IN o NOT EXIST, de la siguiente forma:
Interseccin utilizando NOT IN
SELECT columna
FROM tabla
WHERE columna NOT IN ( SELECT columna
FROM tabla
[WHERE condiciones])
Ao 2010
Pgina 13
SELECT columna
FROM tabla
WHERE NOT EXISTS (SELECT *
FROM tabla
WHERE condiciones)
La siguiente consulta ilustra la operacin diferencia de conjuntos en SQL:
(C19) Averiguar el idm de todos los marineros que han reservado barcos rojos pero no verdes.
SELECT M.idm
FROM Marineros M, Reservas R, Barcos B
WHERE M.idm=R.idm AND R.idb=B.idb
AND B.color=rojo
EXCEPT
SELECT M2.idm
FROM Marineros M2, Reservas R2, Barcos B2
WHERE M2.idm=R2.idm AND R2.idb=B2.idb
AND B2.color=verde
Los marineros 22, 64 y 31 han reservado barcos rojos. Los marineros 22, 74 y 31 han reservado
barcos verdes. Por lo tanto, la respuesta contiene solo el idm 64.
En realidad, dado que la relacin Reservas contiene informacin sobre los idms, no hay necesidad
alguna de consultar a la relacin Marineros, y se puede simplificar la consulta de la siguiente
manera:
SELECT R.idm
FROM Reservas R, Barcos B
WHERE R.idb=B.idb AND B.color=rojo
EXCEPT
SELECT R2.idm
FROM Reservas R2, Barcos B2
WHERE R2.idb=B2.idb AND B2.color=verde
Obsrvese que esta consulta confa en la integridad referencial; es decir, no hay reservas de
marineros que no existan. Tengamos en cuenta que UNION, INTERSECT y EXCEPT se pueden
emplear en cualquier par de tablas compatibles con la unin, es decir, que tengan el mismo
nmero de columnas y esas columnas, tomadas en orden, se correspondan sus dominios. Por
ejemplo se puede escribir la siguiente consulta:
(C20) Averiguar el idm de los marineros que tengan una categora de 10 o hayan reservado el
barco 104.
SELECT M.idm
FROM Marineros M,
WHERE M.categora=10
UNION
SELECT R.idm
FROM Reservas R,
WHERE R.idb=104
Ing. Carolina Orcola
Ao 2010
Pgina 14
La primer parte de la unin devuelve los idms 58 y 71. La segunda parte devuelve 22 y 31. La
respuesta es, por lo tanto, el conjunto de idms 22, 31, 58 y 71. Un ltimo punto a destacar sobre la
UNION, INTERSECT y EXCEPT es: a diferencia del criterio predeterminado de que de la forma
bsica de las consultas no se eliminan los duplicados a menos que se especifique DISTINCT, el
criterio predeterminado para las consultas UNION es que los duplicados s se eliminan, a menos
que escribamos UNION ALL, que fuerza a dejar los duplicados. Igual para el caso de
INTERSECT ALL o de EXCEPT ALL.
Consultas Anidadas
Volvamos a las subconsultas o consultas anidadas, dando ejemplos de su uso. A manera de
ejemplo reescribiremos la siguiente consulta empleando una subconsulta anidada:
(C1) Averiguar el nombre de los marineros que han reservado el barco 103
SELECT M.nombrem
FROM Marineros M,
WHERE M.ide IN (SELECT R.idm
FROM Reservas R,
WHERE R.ide = 103)
La subconsulta anidada calcula el (multi)conjunto de idms de los marineros que han reservado el
barco 103 (el conjunto contiene 22, 31 y 74 para los ejemplares R2 y M3) y la consulta de nivel
superior recupera el nombre de los marineros cuyo idm se halla en ese conjunto. El operador IN,
como ya vismos antes, permite comprobar si un valor pertenece a un conjunto de elementos dado.
Veamos que para averiguar todos los marineros que NO reservaron el barco 103 bastara con
sustituir IN por NOT IN.
Veamos ahora un ejemplo de consulta con varios anidamientos:
(C2) Averiguar el nombre de los marineros que han reservado barcos rojos.
SELECT M.nombrem
FROM Marineros M,
WHERE M.idm IN ( SELECT R.idm
FROM Reservas R,
WHERE R.idb IN ( SELECT B.idb
FROM Barcos B,
WHERE B.color = rojo))
La subconsulta ms interna busca el conjunto de idbs de los barcos rojos (102 y 104 para el
ejemplar B1). La subconsulta que se halla un nivel por encima de ella busca el conjunto de idms
de los marineros que han reservado algunos de esos barcos. Para los ejemplares B1, R2 y M3
ese conjunto de idms contiene 22, 31 y 64. La consulta de nivel superior busca el nombre de los
marineros que pertenecen a ese conjunto de idms; y se obtiene Dominguez, Lorca y Horacio.
Para averiguar el nombre de los marineros que NO han reservado barcos rojos, se sustituye la
aparicin ms externa de IN por NOT IN, de la siguiente manera:
SELECT M.nombrem
FROM Marineros M,
WHERE M.idm NOT IN ( SELECT R.idm
FROM Reservas R,
WHERE R.idb IN ( SELECT B.idb
FROM Barcos B,
WHERE B.color = rojo))
Esta consulta calcula el nombre de los marineros cuyo idm no pertenece al conjunto 22, 31 y 64.
Consultas anidadas correlacionadas
En las consultas anidadas vistas hasta el momento la subconsulta interior ha sido completamente
independiente de la consulta exterior. En general la subconsulta interior puede depender de la fila
que se est examinando en cada momento en la consulta exterior (en trminos de la estrategia de
evaluacin conceptual). Reescribamos una vez ms la siguiente consulta:
Ing. Carolina Orcola
Ao 2010
Pgina 15
(C1) Averiguar el nombre de los marineros que han reservado el barco 103
SELECT M.nombrem
FROM Marineros M,
WHERE EXIST ( SELECT *
FROM Reservas R,
WHERE R.ide = 103 AND R.idm = M.idm)
El operador EXIST, como se vi antes, es otro operador para la comparacin de conjuntos, como
IN, permite comprobar si un conjunto no est vaco. Por lo tanto, para cada fila M de Marineros,
se comprueba si el conjunto de filas de Reservas R tal que R.ide = 103 AND R.idm = M.idm no
est vaco. Si no lo est, el marinero M ha reservado el barco 103 y se devuelve su nombre. La
subconsulta depende claramente de la fila actual M y se debe volver a evaluar para cada fila de
Marineros. La aparicin de M en la subconsulta se denomina correlacin, y estas consultas se
denominan consultas correlacionadas.
Esta consulta tambin ilustra el empleo del smbolo especial * en situaciones en las que todo lo
que se desea hacer es comprobar si existe una fila que cumpla la condicin y no se desea
realmente recuperar ninguna columna de esa fila.
Como ejemplo adicional, mediante el empleo de NOT EXIST en lugar de EXIST, se puede
calcular el nombre de los marineros que no han reservado barcos rojos. Estrechamente
relacionado con EXIST est el predicado UNIQUE. Cuando se aplica UNIQUE a una
subconsulta, la condicin resultante devuelve verdadero si ninguna fila aparece dos veces en la
respuesta de la subconsulta, es decir, si no hay ningn duplicado; en especial devuelve
verdadero si la respuesta est vaca.
Ms ejemplos de consultas anidadas
Veamos ms ejemplos de consultas anidadas:
(C6) Averiguar el nombre de los marineros que han reservado barcos rojos y verdes.
SELECT M.nombrem
FROM Marineros M, Reservas R, Barcos B,
WHERE M.idm=R.idm AND R.idb=B.idb AND B.color=rojo
AND M.idm IN ( SELECT M2.idm
FROM Marineros M2, Reservas R2, Barcos B2,
WHERE M2.idm=R2.idm AND R2.idb=B2.idb
AND B2.color=verde)
Esta consulta se la puede entender de la siguiente manera: Averiguar todos los marineros que
han reservado barcos rojos y, adems, tienen idms que estn incluidos en el conjunto de idms de
marineros que han reservado barcos verdes. Esta formulacin de la consulta ilustra la manera en
la que las consultas que implican a INTERSECT se pueden reescribir usando IN, lo que es muy
til saber cuando el sistema no soporta INTERSECT. Las consultas que emplean EXCEPT se
pueden reescribir de manera parecida usando NOT IN. Para averiguar los idms de los marineros
que han reservado barcos rojos pero no barcos verdes basta con sustituir la palabra clave IN de
la consulta anterior por NOT IN.
SELECT M.nombrem
FROM Marineros M,
WHERE M.idm IN ( (SELECT R.idm
FROM Reservas R, Barcos B,
WHERE R.idb=B.idb AND B2.color=rojo)
INTERSECT
(SELECT R2.idm
FROM Reservas R2, Barcos B2,
WHERE R2.idb=B2.idb AND B2.color=verde) )
Ao 2010
Pgina 16
Como se puede ver en la consulta anterior, escribir la consulta (C6) empleando INTERSECT
resulta ms complicado porque hay que utilizar los idms para identificar a los marineros (durante
la interseccin) y hay que devolver el nombre de los marineros.
El siguiente ejemplo ilustra la manera que se puede expresar en SQL la operacin divisin del
lgebra relacional:
(C9) Averiguar el nombre de los marineros que han reservado todos los barcos.
SELECT M.nombrem
FROM Marineros M,
WHERE NOT EXIST ( (SELECT B.idb
FROM Barcos B,
EXCEPT
(SELECT R.idb
FROM Reservas R,
WHERE R.idm=M.idm) )
Obsrvese que esta consulta est correlacionada para cada miembro de M se comprueba si el
conjunto de barcos reservados por M incluye todos los barcos-. Una manera alternativa de llevar a
cabo la consulta sin emplear EXCEPT es la siguiente:
SELECT M.nombrem
FROM Marineros M,
WHERE NOT EXIST ( (SELECT B.idb
FROM Barcos B,
WHERE NOT EXIST (SELECT R.idb
FROM Reservas R,
WHERE R.idb=B.idb
AND R.idm=M.idm) )
De manera intuitiva, para cada marinero se comprueba que no hay ningn barco que no haya sido
reservado por ese marinero.
Operadores de agregacin
Adems de recuperar datos, a menudo se desea llevar a cabo algn clculo o resumen en las
consultas. SQL permite el empleo de expresiones aritmticas, pero adems permite el uso de
operadores de agregacin, tales como MIN o SUM, que representan una ampliacin significativa
del lgebra relacional. SQL soporta cinco operadores de agregacin, que se pueden aplicar a
cualquier columna de una relacin dada, a saber:
COUNT ([DISTINCT] columna): el nmero de valores (nicos) de la columna en cuestin.
SUM ([DISTINCT] columna): suma de todos los valores (nicos) de la columna en cuestin.
AVG ([DISTINCT] columna): promedio de todos los valores (nicos) de la columna.
MAX (columna): el valor mximo de la columna en cuestin.
MIN (columna): el valor mnimo de la columna en cuestin.
Veamos ejemplos:
(C25) Averiguar el promedio de edad de los marineros.
Ao 2010
Pgina 17
Para averiguar la edad del marinero ms joven (o ms viejo) se puede usar MIN (o MAX) en lugar
de AVG. Ahora, si adems queremos el nombre de ese marinero, no es tan simple como poner
SELECT MIN M.edad, M.nombrem. Esta consulta es ilegal en SQL (si la clusula SELECT
emplea una operacin de agregacin, solo debe emplear operaciones de agregacin, a menos
que la consulta contenga alguna clusula GROUP BY). Por lo tanto habra que escribir:
SELECT M.nombrem
FROM Marineros M
WHERE M.edad > ( SELECT MAX (M2.edad)
FROM Marineros M2
WHERE M2.categora=10)
Empleando ALL esta consulta se podra escribir:
SELECT M.nombrem
FROM Marineros M
WHERE M.edad > ALL (SELECT M2.edad
FROM Marineros M2
WHERE M2.categora=10)
La consulta usando ALL es ms susceptible de sufrir errores. El empleo de ANY se corresponde
con el de MIN en lugar de MAX.
Ao 2010
Pgina 18
Ao 2010
Pgina 19
(C32) Averiguar la edad del marinero ms joven que tiene derecho a voto (es decir, es mayor a 18
aos) para cada categora que tenga, como mnimo, dos marineros con derecho a voto.
Ao 2010
Pgina 20
La siguiente es una formulacin alternativa de la consulta, que ilustra cmo la clusula HAVING
puede tener subconsultas anidadas, al igual que la clusula WHERE. Observemos que se puede
emplear M.categora dentro de la consulta anidada de la clusula HAVING, ya que tienen un solo
valor para el grupo actual de marineros:
Ao 2010
Pgina 21
Esta alternativa trae a colacin varios puntos interesantes. En primer lugar, la clusula FROM
tambin puede contener subconsultas anidadas de acuerdo con las normas de SQL (aunque no
todos los SGBD lo soportan). En segundo lugar, la clusula HAVING no es necesaria en lo
absoluto. Cualquier consulta con clusula HAVING se puede reescribir sin ella, pero muchas
consultas resultan ms sencillas de expresar usndola. Finalmente, cuando aparecen
subconsultas en la clusula FROM, es necesario emplear la palabra clave AS para darle nombre
(ya que en caso contrario no se puede expresar, por ejemplo, Temp.numcateg > 1).
(C37) Averiguar las categoras para las que la edad media de los marineros es mnima.
Esta consulta la usamos para ejemplificar que en las operaciones de agregacin no se permite
anidar. Podramos escribirla errneamente se la siguiente manera:
SELECT M.categora,
FROM Marineros M
WHERE AVG (M.edad) = ( SELECT MIN(AVG (M2.edad))
FROM Marineros M2
GROUP BY M2.categora)
Esta consulta no funcionara aunque se permitiera hacer MIN(AVG(M2.edad)), lo cual es ilegal. En
la consulta anidada, Marineros se divide en grupos por categoras y la edad media se calcula para
cada valor de la categora. Para cada grupo, la aplicacin de MIN a este valor medio de la edad
del grupo devuelve el mismo valor. A continuacin veremos una versin correcta de esta consulta.
Valores nulos
Hasta ahora se ha asumido que los valores de las columnas para una fila dada siempre son
conocidos. En la prctica, los valores de las columnas pueden ser desconocidos. Por ejemplo,
cuando un marinero, por ejemplo dani, se hace socio de un club nutico, puede que no tenga
todava categora asignada. Dado que la definicin de la tabla Marineros tiene una columna
categora, qu fila hay que insertar para Dani? Lo que hace falta es un valor especial que denote
desconocido.
SQL ofrece un valore especial para los valores desconocidos denominado NULL (nulo) para
emplearlo en estas situaciones. Se emplea NULL cuando el valor de la columna es desconocido o
inaplicable. Esta existencia de valores NULL complica muchas situaciones en el uso de SQL.
Comparaciones que emplean valores nulos
Consideremos una comparacin como categora=8. Si se aplica a la fila de Dani, esta condicin
es verdadera o falsa? Dado que la categora de Dani es desconocida, el resultado de esta
comparacin debera ser desconocido, y de hecho es as en SQL. SQL tambin ofrece, como ya
vimos antes, el operador de comparacin especial IS NULL o IS NOT NULL.
Las conectivas lgicas AND, OR y NOT
Consideremos ahora expresiones booleanas como categora = 8 OR edad < 40, y categora = 8
AND edad < 40. Tomando a Dani nuevamente como ejemplo, como Dani es < 40, esa parte de la
comparacin toma el valor verdadero, independientemente del valor de categora, pero qu
ocurre con esa segunda parte? Solo podemos decir desconocido, como vimos antes.
Ao 2010
Pgina 22
Ao 2010
Pgina 23
JOINs o Reuniones
Existe una sintaxis ms concreta para realizar la operacin de reunin, donde la clusula WHERE
se usa nicamente para filtrar registros y no para reunir registros.
Reunin interna - clusulas inner join / on
Esta clusula est diseada precisamente para reunir registros de varias tablas, en ella
intervienen las claves primarias y forneas, y no intervienen, o lo hacen en la clusula WHERE, los
filtros propiamente dichos.
SELECT <select_list>
FROM Table_A A INNER JOIN Table_B B
ON A.Key = B.Key
Si antes se dijo que el SGBD realiza el producto cartesiano entre
dos tablas y posteriormente mediante la clusula WHERE ignora
aquellos registros que carecen de sentido y muestra los que
guardan una relacin, ahora podemos verlo del siguiente modo: el
SGBD recorrer la tabla A y para cada uno asociar el registro de la tabla B que satisface la
clusula ON.
Reunin externa - left outer join / right outer join
La reunin externa puede verse como una reunin interna donde no es necesario que el registro
hijo tenga informada la clave fornea para ser mostrado. La reunin externa siempre se realizara
por la izquierda o por la derecha, una de las dos. De este modo expresamos el deseo de
considerar todos los registros de la tabla a la izquierda o a la derecha de la clusula OUTER
JOIN, aunque no se hallen coincidencias con la otra tabla segn la clusula ON.
SELECT <select_list>
FROM Table_A A RIGHT JOIN Table_B B
ON A.Key = B.Key
SELECT <select_list>
FROM Table_A A LEFT JOIN Table_B B
ON A.Key = B.Key
Ao 2010
Pgina 24
Ao 2010
Pgina 25
Bibliografa
(1) Sistema de Administracin de Bases de Datos; Raghu Ramakrishnan/Johannes
Gehrke; Mc Graw Hill, 3 Edicin, edicin en espaol 2007
La mayora de los contenidos de este apunte son extrados de este libro, con
ejemplos y grficos incluidos.
(2) Fundamentos de Sistemas de Bases de Datos; Elmasri y Navathe; Addison Wesley; 3
Edicin; Madrid; 2002.
(3) Introduccin a las bases de datos relacionales; Mendelzon-Ale; Prentice may; 1 edicin;
Argentina; 2000.
(4) Concepto y diseo de bases de datos; Miguel Mario Piattini; Addison-Wesley.
(5) Fundamentos de base de datos; Korth F. Henry; McGraw Hill; 3 Edicin; 1998.
(6) Introduccin a los sistemas de base de datos; C. J. Date; Prentice-Hall; 7 Edicin; 2001.
(7) Sistemas de Bases de Datos Conceptos fundamentales; Elmasri y Navathe; Addison
Wesley; 2 Edicin; Madrid; 1994.
Ao 2010
Pgina 26