You are on page 1of 42

Práctica 3: Lenguaje SQL

1ª Parte: Manipulación de Bases de Datos

Silvia Abrahão - DSIC curso 2010/2011

Objetivos
•! Presentar •! Ver

la sintaxis del lenguaje SQL (sólo del Lenguaje de Manipulación). algunos ejemplos sencillos para clarificar la semántica del SQL. las bases de datos CICLISMO, MÚSICA y BIBLIOTECA. de menor a mayor complejidad consultas SQL sobre dichas bases de datos. todo lo anterior usando la herramienta SQL del sistema de gestión de bases de datos ORACLE.

•! Presentar •! Realizar •! Realizar

1

Lenguaje de Manipulación del SQL
Se presentan las instrucciones que se pueden ejecutar desde un intérprete de SQL, lo que se denomina SQL interactivo. SQL es un lenguaje muy expresivo y, en general, permite muchas formas de expresar las mismas órdenes. Las cuatro instrucciones que componen el lenguaje de manipulación de datos son las siguientes:
!! SELECT: permite la declaración de consultas para la recuperación de información de una o más tablas de una base de datos. !! INSERT: realiza la inserción de una o varias filas sobre una tabla. !! DELETE: permite efectuar el borrado de una o varias filas de una tabla. !! UPDATE: realiza una modificación de los valores de una o más columnas de una o varias filas de una tabla.

1.1. Consultas: instrucción SELECT
SELECT [ALL | DISTINCT] comalista_item_seleccionado | * FROM comalista_referencia_tabla [WHERE expresión_condicional] [GROUP BY comalista_referencia_col] [HAVING expresión_condicional] [ORDER BY comalista_referencia_col]
"! "! "! "! "! "!

comalista_item_seleccionado: información a obtener de la base de datos. FROM comalista_referencia_tabla: especifica de qué tablas se obtiene la información buscada. WHERE expresión_condicional: expresa una condición que deben cumplir las filas de la consulta resultante. GROUP BY comalista_referencia_col: permite formar consultas agrupadas para extraer información global sobre los grupos formados. HAVING expresión_condicional: condición sobre los grupos formados. ORDER BY comalista_referencia_col: ordena por una o varias columnas.

2

1.1.1. Condiciones en consultas simples
SELECT [ALL | DISTINCT] comalista_ítem_seleccionado | * FROM tabla [WHERE expresión_condicional] [ORDER BY comalista_referencia_col]
"! "! "! "!

ALL : Permite la aparición de filas idénticas (valor por defecto). DISTINCT: No permite la aparición de filas idénticas. La expresión_condicional está formada por un conjunto de predicados combinados con las conectivas lógicas AND, OR y NOT. Los predicados utilizados permiten comparar columnas: predicados de comparación: =, <>, >, <, >=, <=. predicado LIKE: permite comparar una tira de caracteres con un patrón. predicado BETWEEN: permite comprobar si un escalar está en un rango. predicado IN: permite comprobar si el valor está dentro de un conjunto. predicado IS NULL: permite comprobar si el valor es nulo.

Ciclismo
EQUIPO (nom_eq: d_eq, director: d_dir) Clave Primaria: {nom_eq} CICLISTA (dorsal: d_dor, nombre: d_nom, edad: d_edad, nom_eq: d_eq)) Clave Primaria: {dorsal} CAj: {nom_eq} hace referencia a EQUIPO VNN: {nom_eq} ETAPA (nºetapa: d_nº, km: d_km, salida: d_sal, llegada: d_lleg, dorsal: d_dor) Clave Primaria: {nºetapa} CAj: {dorsal} hace referencia a CICLISTA PUERTO (nombre:d_nom,altura:d_alt,categoría:d_cat, nºetapa:d_nº,dorsal: d_dor) Clave Primaria: {nombre} CAj: {nºetapa} hace referencia a ETAPA CAj: {dorsal} hace referencia a CICLISTA VNN: {nºetapa} MAILLOT (código: d_código, tipo: d_tipo, premio: d_pre, color: d_col) Clave Primaria: {código} LLEVAR (dorsal: entero, nºetapa: d_nº, código: d_código) Clave Primaria: {nºetapa, código} CAj: {nºetapa} hace referencia a ETAPA CAj: {dorsal} hace referencia a CICLISTA CAj: {código} hace referencia a MAILLOT VNN: {dorsal}

3

Ciclismo
Equipo nomeq director Ciclista dorsal nombre edad Llevar dorsal netapa codigo Maillot codigo tipo premio color

Etapa
netapa km salida llegada dorsal

nomeq

Puerto nompuerto
altura categoria pendiente netapa dorsal

Esquema de Prácticas.

EJEMPLO: Obtener el nombre y la altura de todos los puertos de 1ª categoría. 1. ¿En qué tablas se encuentra la información? 2. ¿Qué condición deben cumplir las filas resultantes? 3. ¿Que información queremos visualizar? 4. ¿Queremos ordenar el resultado por alguna columna?

SELECT nombre, altura FROM Puerto WHERE categoria = 1;

4

2ª o 3ª categoría. …. exp2. SELECT nombre FROM Ciclista WHERE edad BETWEEN 20 AND 30. expn) ! (exp=exp1) or (exp=exp2) or…or (exp=expn) EJEMPLO: Obtener todos los datos de aquellos ciclistas de los que se desconocía su edad. EJEMPLO: Obtener el nombre de los puertos de 1ª. (*) También el predicado IN es derivado y la expresión equivalente es: exp in (exp1. 5 . SELECT nompuerto FROM Puerto WHERE categoría IN ( 1. SELECT netapa FROM Etapa WHERE llegada LIKE ‘_O%’ OR salida LIKE ‘%A%A%’. 3 ) . SELECT * FROM Ciclista WHERE edad IS NULL. SELECT nombre. EJEMPLO: Obtener el nombre de los ciclistas cuya edad está entre 20 y 30 años.EJEMPLO: Obtener el nombre y la edad de todos los ciclistas. edad FROM Ciclista. (*) El predicado BETWEEN es equivalente a una condición con comparaciones de la siguiente forma: exp between exp1 and exp2 ! (exp >= exp1) and (exp <= exp2) EJEMPLO: Obtener el número de las etapas donde el nombre de la ciudad de llegada tenga por segunda letra una “O” o donde el nombre de la ciudad de salida lleve dos o más ‘A’s. 2.

Ejemplo de consulta incorrecta (error de sintaxis) SELECT nomeq FROM Equipo WHERE director = null La consulta correcta sería SELECT nomeq FROM Equipo WHERE director IS NULL 6 . el resultado de la comparación sería indefinido y por tanto dicha fila no se incluiría en la selección. Ejemplo: select * from T where atrib1 > atrib2 Si en una fila se diera el caso que atrib1 = 50 y atrib2 fuera nulo.COMPARACIÓN DE VALORES NULOS Las comparaciones entre cualquier valor y NULL resultan en indefinido.

premio / 150 FROM Maillot WHERE premio / 150 > 100. da como resultado el cardinal del conjunto de filas de la selección. Si el número de filas de la selección es 0. la función COUNT devuelve el valor 0 y las otras funciones el valor nulo. EJEMPLO: Obtener de los maillots el tipo y el premio en dólares (supongamos que está en pesetas) ($1 = 150 ptas. / (división). La función especial COUNT(*). en la que no está permitido incluir DISTINCT ni ALL.(diferencia). Para las funciones SUM y AVG los argumentos deben ser numéricos. SELECT nombre.) de aquellos maillots cuyo premio supere los 100 dólares. Los cálculos se realizan después de la selección y aplicar las condiciones. Los valores nulos son eliminados antes de realizar los cálculos (incl. Uso de LIKE EJEMPLO: Obtener el nombre y la edad de los ciclistas que pertenezcan a equipos cuyo nombre contenga la cadena “100%”. DISTINCT indica que los valores redundantes sean eliminados antes de que se realice el cálculo correspondiente. edad FROM Ciclista WHERE nomeq LIKE ‘%100\%%’ ESCAPE ‘\’ Se ha utilizado ‘\’ para indicar que el carácter comodín tiene su valor ‘%’ CONSULTAS DE VALORES AGREGADOS La sintaxis de una referencia a una función agregada es la siguiente: { avg | max | min | sum | count } ( [all | distinct] expresión_escalar ) | count(*) "! "! "! "! "! "! "! Las funciones agregadas no se pueden anidar.MÁS EJEMPLOS DE COMPARACIONES Uso de operadores aritméticos: + (suma). 7 . * (producto). etc. SELECT tipo. count). .

FUNCIONES AGREGADAS EN CONSULTAS NO AGRUPADAS EJEMPLO: SELECT ‘Núm. COUNT(*). AVG(edad) FROM Ciclista WHERE nomeq = ‘Banesto’. AVG(edad) FROM Ciclista WHERE nomeq = ‘ONCE’. de ciclistas =’. la selección sólo podrá incluir referencias a funciones agregadas o literales ya que las funciones van a devolver un único valor. ‘Media Edad =’. En consultas no agrupadas. Ejercicios: Práctica 3: El lenguaje SQL (1a Parte) Hacer el bloque de consultas sobre una sola relación de las bases de datos Ciclismo y Música 8 . EJEMPLO INCORRECTO: SELECT nombre.

3.CONSULTAS SIMPLES SOBRE VARIAS TABLAS Cuando la información que se desea obtener de la base de datos se encuentra almacenada en más de una tabla se hace indispensable el declarar una consulta que manipule estas tablas. 9 . ¿Qué información queremos visualizar? SELECT etapa.netapa. ¿En qué tablas se encuentra la información? FROM Etapa. Puerto WHERE etapa. 1.dorsal = puerto. nompuerto En esta expresión es obligatorio que la referencia a la columna dorsal de Etapa y Puerto sea calificada con el nombre de la tabla. nompuerto FROM Etapa.dorsal.netapa. ==> SELECT etapa. si no es ambigua.dorsal = puerto. Puerto 2.dorsal. EJEMPLO: Obtener pares de números de etapas y nombres de puertos ganados por el mismo ciclista. ¿Qué condición deben cumplir las filas resultantes? WHERE etapa.

Es virtual "! Por tanto.columna Es una instancia de la tabla. entonces se utilizan las variables de recorrido [tabla | variable_recorrido].n = T2. permiten dar un nombre alternativo a la misma tabla dentro de una consulta.Ejemplo: SELECT * FROM T1. La manera de declarar una variable de recorrido es: FROM tabla [as] variable_recorrido 10 .n T1 n a1 a2 a3 b1 b2 b3 c1 c2 T2 n d1 b2 T1 x T2 n X X X "! X X n c1 c2 c1 c2 c1 c2 d1 b2 d1 b2 d1 b2 a1 a1 a2 a2 a3 a3 b1 b1 b2 b2 b3 b3 Cont. Consulta en varias tablas "! Cuando se va a trabajar con una tabla para hacer consulta entre diferentes tuplas de ella. T2 WHERE T1.

¿Qué condición deben cumplir las filas resultantes? WHERE C2. SELECT C.edad.dorsal = E. número de etapa.edad.edad < C2.nomeq AND C1. 3. Ciclista C2 WHERE C2.edad < C2.nombre. Ciclista C2 2. ¿Qué información queremos visualizar? SELECT DISTINCT C1.nombre=‘Miguel Induráin’ AND C1.nomeq AND C1.director = ‘Álvaro Pino’. E.dorsal AND E. SELECT C. 11 .nombre=‘Miguel Induráin’ AND C1. de tal forma que dicho ciclista haya ganado dicha etapa. EJEMPLO: Obtener los nombres de los ciclistas pertenecientes al equipo dirigido por ‘Álvaro Pino’. entonces se necesita tener varias imágenes de ella FROM Ciclista C1. Además la etapa debe superar los 150 km. Equipo E WHERE C.nombre ==> SELECT DISTINCT C1. EJEMPLO: Obtener pares nombre de ciclista.nombre FROM Ciclista C1. Etapa E WHERE C. USO DE CLAVES AJENAS EN CONSULTAS DE VARIAS TABLAS Si existen claves ajenas.nomeq AND E.nomeq = E. como se requiere comparar con tuplas de la misma tabla. de recorrido. lo normal es que se dé una igualdad entre la clave ajena y los atributos correspondientes de la tabla a la que se hace referencia.km > 150.netapa FROM Ciclista C. ¿En qué tablas se encuentra la información? FROM Ciclista Pero.EJEMPLO: Obtener el nombre de los ciclistas compañeros de equipo de ‘Miguel Induráin’ que sean más jóvenes que él.nomeq = C2.nombre FROM Ciclista C. 1.nomeq = C2.

nomeq FROM Ciclista C2 WHERE C2. entonces también se pueden utilizar las subconsultas para expresar este tipo de condiciones. 12 . (Es el mismo enunciado de antes) SELECT C1. EJEMPLO: Obtener el nombre de los ciclistas compañeros de equipo de ‘Miguel Induráin’ que sean más jóvenes que él.nombre FROM Ciclista C1 Tablas que se requieren para el Select precedente WHERE C1.edad FROM Ciclista C2 WHERE C2.edad < (SELECT C2.nombre=‘Miguel Induráin’).nombre=‘Miguel Induráin’) Se verá más adelante AND C1.Ejercicios: Práctica 3: El lenguaje SQL (1a Parte) Hacer el bloque de consultas sobre varias tablas de las bases de datos Ciclismo y Música CONSULTAS COMPLEJAS: SUBCONSULTAS Si la información que se está buscando está incluida en una tabla y la condición de búsqueda de esta información requiere acceder a otras tablas.nomeq IN (SELECT C2.

EJEMPLO: Obtener los nombres de los ciclistas pertenecientes al equipo dirigido por ‘Álvaro Pino’. Equipo E WHERE C. •! MATCH: comprueba si un valor es idéntico a algún valor de una colección. Usando subconsultas. PREDICADOS QUE ACEPTAN SUBCONSULTAS Las subconsultas pueden aparecer en las condiciones de búsqueda.director = ‘Álvaro Pino’). se habían usado igualdades: SELECT C. nombre del ciclista.nomeq = (SELECT E.director = ‘Álvaro Pino’. 13 .nomeq FROM Equipo E WHERE E.nombre FROM Ciclista C C. <=). Los predicados que pueden llevar como argumentos subconsultas son los siguientes: •! predicados de comparación (=. •! UNIQUE: comprueba si una subconsulta no devuelve filas repetidas. como argumentos de algunos predicados.nomeq = E. <.nomeq AND E. <>. tanto de la cláusula WHERE como de la HAVING. •! EXISTS: equivalente al cuantificador existencial. sería: SELECT C. Antes.nombre FROM Ciclista C. >=. WHERE Esto es posible porque la información que se requiere. >. •! predicados de comparación cuantificados (ANY y ALL): permitir comparar un valor con un conjunto de valores. comprueba si una subconsulta devuelve alguna fila. no está en la tabla de la subconsulta (Equipo) y porque la subconsulta retorna un único valor. •! IN: comprueba que un valor pertenece a una colección dada mediante una subconsulta.

en general se verán subconsultas de una única columna. <>. <>. >=). <. B2.una fila ==> WHERE altura > (SELECT AVG(altura) FROM Puerto WHERE categoria = ‘2’ ). 1. An) predicado_comparación (B1. siempre y cuando devuelvan una única fila y el número de columnas coincida en número y tipo con el otro lado del predicado de comparación. >=.PREDICADOS DE COMPARACIÓN (=. A2. ¿Qué condición deben cumplir las filas resultantes? altura > AVG(altura) de los Puertos de segunda categoría Es un valor . existe una forma definida de realizar esta comparación para cada uno de los predicados de comparación (=. !. Compara cada valor de altura con el valor obtenido en avg(altura) 14 . constructor_fila predicado_comparación constructor_fila En el caso que la subconsulta esté vacía. <=. Bn) Las subconsultas pueden ser argumentos. !. Llamaremos constructor_fila a una lista de atributos entre paréntesis o una subconsulta. EJEMPLO: Obtener los nombres de los puertos cuya altura es mayor que la media de altura de los puertos de 2ª categoría. >. >. Es decir: (A1. como el ejemplo anterior. se convierte a una fila con valores nulos en todas las columnas. Pero. Para poder comparar dos constructor_fila de más de una columna. <. ¿En qué tablas se encuentra la información? Puerto ==> FROM Puerto 2. <=) Cada uno de los dos lados de un predicado de comparación debe ser una única tupla formada por el mismo número de columnas.

EJEMPLO: Obtener los nombres de los puertos cuya altura es mayor que la media de altura de los puertos de 2ª categoría. ¿En qué tablas se encuentra la información? Puerto ==> FROM Puerto 2. 1. ¿Qué condición deben cumplir las filas resultantes? altura > avg(altura) de los Puertos de segunda categoría ==> WHERE altura > (SELECT AVG(altura) FROM Puerto WHERE categoria = ‘2’ ). ¿Qué información queremos visualizar? nompuerto ==> ==> SELECT nompuerto SELECT nompuerto FROM Puerto WHERE altura > (SELECT AVG(altura) FROM Puerto WHERE categoria = ‘2’ ). Es un valor a la vez ==> No puede hacer la comparación INCORRECTO: (error de ejecución) 15 . ¿Qué hace el siguiente ejemplo? ¿Es correcto? SELECT nompuerto FROM Puerto 1 columna con n filas WHERE altura > (SELECT altura FROM Puerto WHERE categoria = ‘2’ ). 3.

SELECT netapa FROM Etapa WHERE dorsal IN (SELECT dorsal FROM Ciclista WHERE nomeq IN (SELECT nomeq FROM Equipo WHERE director LIKE ‘A%’)). con IN Encadenadas: se pueden hacer Subconsultas EJEMPLO: Obtener el número de las etapas ganadas por ciclistas que pertenezcan a equipos cuyo director tenga un nombre que empiece por ‘A’. 16 . SELECT netapa FROM Etapa WHERE dorsal IN (SELECT dorsal FROM Ciclista WHERE edad > 30). También. EJEMPLO: Obtener el nº de las etapas ganadas por ciclistas con edad superior a los 30 años.Predicado IN Comprueba que un valor pertenece a una colección dada mediante una subconsulta constructor_fila [not] IN(expresión_tabla) A la derecha de IN puede aparecer más de una fila y por eso se denomina expresión_tabla.

dorsal AND P.Predicados de comparación cuantificados (ALL. •! El predicado de comparación cuantificado con ANY o SOME se evalúa a cierto si lo es para alguna fila de la expresión de tabla (si la tabla está vacía se evalúa a falso).pendiente FROM Puerto P1 ) ) 17 . SELECT P.pendiente > ANY (SELECT P1.pendiente < ALL (SELECT P1.pendiente FROM Puerto P1 ) EJEMPLO: Obtener el nombre de los puertos y de los ciclistas que los hayan ganado. ANY) Permiten comparar un valor con un conjunto de valores. Ciclista C WHERE P.nompuerto. (*) el predicado IN es idéntico al predicado de comparación cuantificado = ANY.pendiente >= ALL (SELECT P1.nombre FROM Puerto P. SELECT P. EJEMPLO: Obtener el nombre de los puertos y de los ciclistas que los hayan ganado que tengan la mayor pendiente.nombre FROM Puerto P.dorsal = C. constructor_fila predicado_comparación {all | any | some} (expresión_tabla) •! El predicado de comparación cuantificado con ALL se evalúa a cierto si lo es para todas las filas de la expresión de tabla (si la tabla está vacía también se evalúa a cierto). C. NOT ( P.pendiente FROM Puerto P1 ) (*) Cualquier ANY se puede convertir en un ALL cambiando la condición a su condición negada y añadiendo un NOT. Ciclista C WHERE P.dorsal = C.nompuerto.dorsal AND P. cumpliendo que el puerto no sea el que tenga la menor pendiente. C.

codigo IN (SELECT M.codigo FROM Maillot M WHERE M.premio < 120 AND M. IN y EXISTS son intercambiables y se pueden eliminar haciendo consultas a múltiples tablas e igualando por claves ajenas.codigo = L.dorsal AND EXISTS (SELECT * FROM Maillot M WHERE M.dorsal = L.premio < 120 ) 18 .nombre FROM Ciclista C.nombre FROM Ciclista C.dorsal = L. EJEMPLO: Obtener el nombre de aquellos ciclistas que han llevado un maillot de un premio menor de 120 euros. Llevar L WHERE C. Llevar L WHERE C.Predicado EXISTS EXISTS (expresión_tabla) •!El predicado EXISTS se evalúa a cierto si la expresión SELECT devuelve al menos una fila.dorsal AND L.codigo) O bien: SELECT C. SELECT C. •!En general.

dorsal). WHERE EXISTS (SELECT * FROM !) equivale a: WHERE 0 < (SELECT COUNT(*) FROM !) WHERE NOT EXISTS (SELECT * FROM !) equivale a: WHERE 0 = (SELECT COUNT(*) FROM !) Ejercicios: Práctica 3: El lenguaje SQL (1a Parte) Hacer el bloque de consultas con subconsultas de las bases de datos Ciclismo y Música 19 .dorsal = Ciclista. SELECT nombre FROM Ciclista WHERE NOT EXISTS (SELECT * FROM Etapa WHERE Etapa.EJEMPLO: Obtener el nombre de los ciclistas que no han ganado etapas.

cod_asg=A.cod_asg)) El lenguaje SQL Problemas con la cuantificación universal Obtener el nombre de los profesores que imparten todas las asignaturas de su departamento de mas de 6 créditos.cod_pro # D.nombre FROM Profesor P WHERE NOT EXISTS (SELECT * FROM Asignatura A WHERE NOT EXISTS (SELECT * FROM Docencia D WHERE D.cod_pro=P.Uso de EXISTS para cuantificación universal (NO HAY EN SQL) $ X F(X) ! % & X % F(X) Obtener el nombre de los profesores que imparten todas las asignaturas. SELECT P. ¿qué pasa si en el departamento de un profesor no hay asignaturas de mas de 6 créditos? 20 .

nombre| Profesor (PX) # $AX ((Asignatura (AX) # AX.teoría+AX.cod_dep= PX.prac)>6) # $AX ( (Asignatura (AX) # AX. {PX. entonces se debe hacer un control para comprobar que en el departamento del profesor existe alguna asignatura de mas de seis créditos!.El lenguaje SQL ¿qué pasa si en el departamento de un profesor PX no hay asignaturas de mas de 6 créditos? FALSO para todo valor de AX {PX.cod_pro = PX.nombre| Profesor (PX) # &AX (Asignatura (AX) # AX.teoría+AX.prac)>6) ' &DX (Docencia (DX) # DX.cod_asg) ) } ¡El profesor PX aparecería en el resultado de la consulta! CIERTO El lenguaje SQL ¡Si estos profesores no deben salir en la consulta.cod_dep # (AX.cod_pro # DX.cod_pro # DX.cod_dep= PX.cod_asg = AX.cod_dep # (AX.cod_dep # (AX.prac)>6) ' &DX (Docencia (DX) # DX.cod_dep= PX.cod_asg) ) } 21 .cod_pro = PX.teoría+AX.cod_asg = AX.

dorsal=X. C.El lenguaje SQL.cod_dep= PX.nombre| Ciclista(C)#% &X(Etapa(X)#X. SELECT PX.cod_asg) ) ) Uso de EXISTS para cuantificación universal $ X F(X) ! % & X % F(X) Obtener el nombre del ciclista que ha ganado todas las etapas de más de 200 km.teoría+AX.cod_dep AND (AX.Km>200'C.nombre| Ciclista(C)#$ X (Etapa(X)#X.cod_dep=PX.teoría+AX.cod_pro AND DX.cod_asg=AX.prac)>6) SQL AND NOT EXISTS (SELECT * FROM Asignatura AX WHERE AX.cod_dep AND (AX.dorsal) 22 .prac)>6 AND NOT EXISTS (SELECT * FROM Docencia DX WHERE DX.cod_pro=PX.dorsal<>X.dorsal) es equivalente a: C.nombre FROM Profesor PX WHERE EXISTS (SELECT * FROM Asignatura AX WHERE AX.Km>200#C.

km > 200 AND C. Uso de “Coletillas” en consultas con cuantificación universal ¿Qué pasa si no hay etapas de más de 200 km? ¡¡¡SALDRÍAN TODOS LOS CICLISTAS!!! Solución: SELECT C. 23 .dorsal <> E. que él no haya ganado” SELECT nombre FROM Ciclista C WHERE NOT EXISTS (SELECT * FROM Etapa E WHERE km > 200 AND C.km > 200).Para poder expresar esta consulta en SQL se convertirá en: “Obtener el nombre del ciclista tal que no existe una etapa de más de 200 km.dorsal ) AND EXISTS (SELECT * FROM ETAPA E2 WHERE E2.dorsal <> E.nombre FROM Ciclista C WHERE NOT EXISTS (SELECT * FROM Etapa E WHERE E.dorsal ).

id_lib:tira(10)) Clave Primaria: {num. autor_id:tira(4)) Clave Primaria: {cod_ob.autor_id} Clave Ajena: {cod_ob}' OBRA Clave Ajena: {autor_id}' AUTOR 24 . id_lib:tira(10)) Clave Primaria: {cod_ob.Ejercicios: Práctica 3: El lenguaje SQL (1a Parte) Hacer el bloque de consultas con cuantificación universal de las BDs Ciclismo y Música AUTOR(autor_id: tira(4). descripcion: tira(50)) Clave Primaria: {tematica} OBRA(cod_ob: entero. num_obras: entero) Clave Primaria: {id_lib} VNN: {titulo} TEMA(tematica: tira(20). nombre: tira(35). año: d_cat. año: entero.id_lib} Clave Ajena: {cod_ob} ' OBRA Clave Ajena: {id_lib} ' LIBRO ESCRIBIR(cod_ob: entero. titulo: tira(80). tematica: tira(20)) Clave Primaria: {cod_ob} Clave Ajena: {tematica}' TEMA VNN: {titulo} AMIGO(num: entero. nombre: tira(60). titulo: tira(80). nacionalidad: tira(20)) Clave Primaria: {autor_id} LIBRO(id_lib: tira(10).id_lib} Clave Ajena: {num} ' AMIGO Clave Ajena: {id_lib} ' LIBRO Biblioteca ESTA_EN(cod_ob: entero. telefono: tira(10)) Clave Primaria: {num} VNN: {nombre} PRESTAMO(num: entero.

A2j.. Bm).. Consultas Complejas Relación Selección-Agrupamiento Un grupo se puede entender como un conjunto de filas con el mismo valor para el conjunto de columnas por las que se agrupa (las incluidas en la cláusula GROUP BY). EJEMPLO: Obtener el nombre de cada equipo y la edad media de los ciclistas de dicho equipo: SELECT nomeq........ Los grupos se definen por la igualdad de valor en los atributos de agrupación (B1.. HAVING: de los grupos definidos se seleccionan aquellos que cumplen la condición expresada. Rn [WHERE condición] [GROUP BY B1.. B2. Nomeq Banesto ONCE PDM Banesto Kelme ONCE Kelme Banesto Edad 22 25 32 25 28 30 29 28 25 . R2.. AVG(edad) FROM Ciclista GROUP BY nomeq.. .Consultas Agrupadas SELECT [ALL | DISTINCT] A1i. Ank| * FROM R1... Bm] [HAVING condición] GROUP BY: define grupos de tuplas en el conjunto de tuplas seleccionadas por la condición WHERE. B2.

Nomeq Banesto Banesto Banesto ONCE ONCE PDM Kelme Kelme Edad 22 25 28 25 30 32 29 28 Un Valor por Grupo Entonces.5 26 .5 32 28. devolviendo un valor por cada grupo formado. es: Nomeq Banesto ONCE PDM Kelme Edad 25 27. AVG(edad) FROM Ciclista GROUP BY nomeq. para SELECT nomeq.Las funciones agregadas en las consultas agrupadas funcionan de forma diferente que en las consultas normales. La solución.

Torralba Mart# nez Ignacio Gil Pechu$n Daniel Gil Tom$s Matilde Celma Gim" nez tel! fono 7796 6789 5760 3560 7439 4590 3423 5679 7756 cod_dep DSIC MAT DISCA DSIC IDM OEM OEM DISCA DSIC cod_dep DSIC 3 SELECT cod_dep. Torralba Mart# nez Ignacio Gil Pechu$n Daniel Gil Tom$s Matilde Celma Gim" nez tel! fono 7796 6789 5760 3560 7439 4590 3423 5679 7756 cod_dep DSIC MAT DISCA DSIC IDM OEM OEM DISCA DSIC cod_dep DSIC MAT DISCA IDM OEM 3 1 2 1 2 SELECT cod_dep. Benlloch Dualde Mar# a Alpuente Frasnedo Cristina P" rez Guillot Jos"M. COUNT (*) FROM Profesor GROUP BY cod_dep Consultas Agrupadas Obtener el número total de profesores de los departamentos que tienen mas de 2 profesores. Casamayor R!denas Robert Fuster i Capilla Jos"V. COUNT (*) FROM Profesor GROUP BY cod_dep HAVING COUNT (*) > 2 27 . cod_pro JCC RFC JBD MAF CPG JTM IGP DGT MCG nombre Juan C. Benlloch Dualde Mar# a Alpuente Frasnedo Cristina P" rez Guillot Jos"M.Consultas Agrupadas EJEMPLO: Obtener el número total de profesores de cada departamento Profesor cod_pro JCC RFC JBD MAF CPG JTM IGP DGT MCG nombre Juan C. Casamayor R!denas Robert Fuster i Capilla Jos"V.

4 1 2 3 SELECT nomeq.EJEMPLO INCORRECTO: SELECT nomeq. GROUP y WHERE Si se incluye la cláusula where. nombre. AVG(edad) FROM Ciclista WHERE edad > 25 GROUP BY nomeq. sólo pueden aparecer referencias a columnas por las cuales se agrupa. AVG(edad) FROM Ciclista GROUP BY nomeq. 28 . la aplicación de esta cláusula se produce previamente a la agrupación. La regla sintáctica que aplican los sistemas relacionales para asegurar el buen funcionamiento de las consultas agrupadas es la siguiente: “En la selección de una consulta agrupada. referencias a funciones agregadas o literales”.

2) En el conjunto de tuplas seleccionadas se definen grupos basados en el valor de los atributos de agrupación.Evaluación: 1) Se seleccionan n tuplas de las relaciones que cumplan la condición de la cláusula WHERE. WHERE y HAVING La cláusula HAVING sólo puede ir en consultas agrupadas y es similar a WHERE. pero en un orden diferente: 1º) Condición WHERE (se usa para las filas) 2º) Agrupamiento y cálculo de valores agregados 3º) Condición HAVING (se usa para los grupos) En la cláusula HAVING sólo podrán aparecer directamente referencias a columnas por las cuales se agrupan o a funciones agregadas. 3) De los grupos definidos se seleccionan los que cumplen la condición de la cláusula HAVING. 29 . GROUP.

EJEMPLO: Obtener el nombre del ciclista y el número de puertos que ha ganado.nombre /* Agrupar siempre por CP */ HAVING AVG (P. de aquellos equipos con más de 3 corredores mayores de 25 años.dorsal.dorsal = P.EJEMPLO: Obtener el nombre de cada equipo y la edad media de sus ciclistas con más de 25 años. SELECT nomeq. Puerto P WHERE C. siendo la media de la pendiente de éstos superior a 10. COUNT(P.nombre.dorsal GROUP BY C. SELECT C. AVG(edad) FROM Ciclista WHERE edad > 25 GROUP BY nomeq HAVING COUNT(dorsal) > 3.nompuerto) FROM Ciclista C.pendiente) >10. 30 . C.

'! Combinaciones conjuntistas de tablas: utilizando operadores de la teoría de conjuntos para combinar las tablas. junto con las ya vistas. "! '! Uso de subconsultas en las condiciones de las cláusulas where o having. '! Concatenaciones de tablas: utilizando diferentes formas variantes del operador concatenación del Álgebra Relacional. en definitiva.Ejercicios: Práctica 3: El lenguaje SQL (1a Parte) Hacer el bloque de “consultas agrudapas” de las BDs Ciclismo y Música COMBINACIONES DE TABLAS Existen otras formas de combinar varias tablas en consultas y todas ellas. varias formas de combinar dos tablas en el lenguaje SQL: " ! '! Incluir varias tablas en la cláusula from. dan lugar a una “expresión de tabla”. Existen. 31 .

. FROM R WHERE F SELECT Ai .. Ak FROM R SELECT .. FROM R1. Dadas dos tablas A y B: '! '! '! UNION: la tabla resultado tendrá las filas de A y B INTERSECT: la tabla resultado tendrá las filas que se encuentren a la vez en A y en B...El Lenguaje Estándar SQL Operador Selección Proyección Producto Cartesiano Concatenación Unión Diferencia Intersección Álgebra Relacional R Donde F R [Ai . o SELECT...FROM R1 CROSS JOIN R2. .. x Rn SQL SELECT . R2. FROM R1 NATURAL JOIN R2 SELECT * FROM R1 UNION SELECT * FROM R2 SELECT * FROM R1 EXCEPT SELECT * FROM R2 SELECT * FROM R1 INTERSECT SELECT * FROM R2 R1 R2 R1 ( R2 R1 . Ak] R1 x R2...... Rn. mismos tipos y nombres).. mismo orden. Aj . EXCEPT: la tabla resultado tendrá las filas de A que no se encuentren en B..... CROSS JOIN Rn SELECT. . .R2 R1 ) R2 COMBINACIONES CONJUNTISTAS DE TABLAS Corresponden a los operadores unión. Permiten combinar tablas que tengan esquemas compatibles (mismo número de elementos seleccionados.... 32 .. intersección y diferencia del Álgebra Relacional. Aj .

UNION expresión_tabla union [ALL] término_tabla Realiza la unión de las filas de las tablas provenientes de las dos expresiones. Se permitirán o no duplicados según se incluya o no la opción ALL. SELECT director FROM Departamento UNION SELECT nombre FROM Profesor 33 . Obtener el nombre de todo el personal (profesores y directores de departamento). EJEMPLO: Obtener el nombre de todo el personal de la vuelta. (SELECT nombre FROM Ciclista) UNION (SELECT director FROM Equipo) UNION Ejemplo 2.

SELECT DISTINCT cod_dep FROM Profesor INTERSECT SELECT DISTINCT cod_dep FROM Asignatura 34 . EJEMPLO: Obtener los nombres de las personas que son tanto ciclistas como directores de equipo . Obtener los departamentos que tienen adscritas asignaturas y profesores. (SELECT nombre FROM Ciclista) INTERSECT (SELECT director FROM Equipo) INTERSECT Ejemplo 2.INTERSECT expresión_tabla intersect término_tabla Realiza la intersección de las filas de las tablas provenientes de las dos expresiones.

el operador EXCEPT se denomina MINUS. Obtener los departamentos que no tienen adscritas asignaturas. (SELECT nombre FROM Ciclista) MINUS (SELECT director FROM Equipo) EXCEPT Ejemplo 2.EXCEPT expresión_tabla except término_tabla En Oracle es Minus Realiza la diferencia de las filas de las tablas provenientes de las dos expresiones. SELECT cod_dep FROM Departamento EXCEPT SELECT DISTINCT cod_dep FROM Asignatura En ORACLE. 35 . EJEMPLO: Obtener los nombres que aparecen en la tabla de ciclistas y no en la de directores.

R2. RIGHT........ .A2j. B2....Concatenación de tablas SELECT [ALL | DISTINCT] A1i.. •! Producto cartesiano – CROSS JOIN •! Concatenación interna – NATURAL JOIN •! Concatenación externa – LEFT... Bm] [HAVING condición] #!concatenación interna: INNER JOIN #!concatenación externa: OUTER JOIN Concatenación de tablas Corresponden a variantes del operador concatenación del Álgebra Relacional.. FULL •! Concatenación unión – UNION JOIN 36 .Ank| * FROM R concatenación 1.. Rde n tablas [WHERE condición] [GROUP BY B1.

ON: combina una fila de cada operando cuando la condición expresada se evalúe a cierta. Concatenación Interna referencia_tabla1 [natural] [inner] join referencia_tabla2 [on expresión_condicional | using (comalista_columna) ] tabla1 join tabla2 on expresión_condicional SELECT * FROM tabla1.. #!Inner Join. tabla2 WHERE expresión_condicional #!Natural Join: se concatenan las tuplas de tabla1 y tabla2 que tienen el mismo valor en todos los atributos del mismo nombre #!Join.. USING: combina una fila de cada operando cuando el valor en las columnas comunes es idéntico. ! 37 .. referencia_tabla2 #!La tabla resultado de la operación CROSS JOIN es el producto cartesiano de las dos tablas operandos.Producto Cartesiano (CROSS JOIN) referencia_tabla1 cross join referencia_tabla2 ! SELECT * from referencia_tabla1..

Cn Es útil cuando no interesa que las relaciones se concatenen por todos los atributos del mismo nombre (NATURAL JOIN).. 38 .cod_pro. nombre... An| * FROM tabla1 JOIN tabla2 USING (C1.. Bm] [HAVING condición] (1) (2) (3) (4) se concatenan las tuplas de tabla1 y tabla2 que tienen el mismo valor en los atributos comunes C1..USING SELECT [ALL | DISTINCT] A1.cod_pro GROUP BY cod_pro concatenación de Profesor y Docencia SELECT cod_pro.cod_asg) FROM Profesor PX.cod_pro = DX.Natural Join SELECT PX. COUNT(DX.. A2.... C2.. B2.. C2. COUNT (cod_asg) FROM Profesor NATURAL JOIN Docencia GROUP BY cod_pro #!Natural Join: se concatenan las tuplas de Profesor y Docencia que tienen el mismo valor en los atributos del mismo nombre (cod_pro) Concatenación JOIN.nombre. Docencia DX WHERE PX.. PX. Cn) [WHERE condición] [GROUP BY B1......Ejemplo..

. Ejemplo: Obtener nombre y director de todos los equipos que tengan ciclistas. A2.nomeq. An| * FROM tabla1 JOIN tabla2 ON condición1 [WHERE condición2] [GROUP BY B1.... B2. Bm] [HAVING condición] (1) (2) (3) (4) se concatenan las tuplas de tabla1 y tabla2 que cumplen condición1 Es útil cuando: #! interesa concatenar tuplas de tabla1 y tabla2 por condiciones distintas de la igualdad.nomeq 39 .nomeq.... e. Forma ya conocida: SELECT e.ON SELECT [ALL | DISTINCT] A1...nomeq ! Empleo del JOIN: SELECT e.nomeq=C. e.Concatenación JOIN.director FROM Equipo E JOIN Ciclista C ON E. Ciclista C WHERE E.director FROM Equipo E.nomeq=C. #! los atributos por los que se desea concatenar no tienen el mismo nombre en ambas relaciones..

Concatenación externa sobre la izquierda: tabla1 left join tabla2 on expresión_condicional (Concat. interna de tabla1 y tabla2) union (tuplas de la tabla1 que no están en la concatenación interna con valores nulos en el resto de columnas) RIGHT ! LEFT con la diferencia de que las tuplas que se muestran son las de tabla2.Concatenación Externa referencia_tabla [natural] {left [outer] | right [outer] | full [outer] } JOIN referencia_tabla [on expresión_condicional | using (comalista_columna) ] FULL. se muestran las tuplas no concatenadas de tabla1 y tabla2 Cont. 40 .

tabla1 union join tabla2 tuplas de tabla1 con valores nulos en las columnas de tabla2 union tuplas de tabla2 con valores nulos en las columnas de tabla1 EJERCICIO 33: Obtener nombre de todos los equipos indicando cuantos ciclistas tiene cada uno 1ª Opción (errónea) – 21 filas SELECT e. que pueden ser distintos.dorsal) FROM (EQUIPO E left join ciclista c on E.NOMEQ) GROUP BY E.nomeq.dorsal) FROM Equipo E.NOMEQ=C.Concatenación Unión referencia_tabla union join referencia_tabla Crea una tabla donde el esquema es la unión de los esquemas de las dos tablas.nomeq=C. count(c.nomeq GROUP BY e.nomeq 2ª Opción Correcta – 22 filas SELECT E. El equipo PDM con 0 ciclistas no aparece 41 .nomeq. Ciclista C WHERE E.nomeq. count(c.

Ciclista C WHERE E.nomeq Se pone (+) en la parte de la ICA de la tabla de la que no se quieren mantener las tuplas 42 .nomeq (+) GROUP BY e.nomeq=C.dorsal) FROM Equipo E. count(c.EJERCICIO 33: Obtener nombre de todos los equipos indicando cuantos ciclistas tiene cada uno 3ª Opción Correcta – 22 filas SELECT e.nomeq.