Está en la página 1de 36

Bases de datos

Capítulo 3: Introducción a SQL - 2


Capítulo 3 – Introducción a SQL – Parte 2

CONTENIDO
Parte 1:
• Comentarios generales sobre SQL
• Definición de datos
• Estructura básica de las consultas
• Operaciones básicas adicionales
• Operaciones sobre conjuntos
• Valores nulos

Parte 2:
• Funciones de agregación
• Subconsultas anidadas
• Modificación de la base de datos
Funciones de agregación
• Las funciones de agregación toman una colección de valores (un conjunto o multiconjunto)
y devuelven un único valor.

• SQL dispone de las siguientes funciones de agregación incorporadas


avg: valor medio (sólo con números)
min: valor mínimo. Si cadena, se queda con el primero por orden alfabético
max: valor máximo. Si cadena, se queda con el último por orden alfabético
sum: suma de valores (sólo con números)
count: número de valores

• La entrada de sum y avg debe ser una colección de números, pero el resto de operadores
pueden operar también con colecciones de tipos de datos no numéricos, como cadenas de
caracteres.
Agregación básica (1/2)
• Los sistemas de bases de datos pueden dar un nombre arbitrario al atributo de la relación
resultado que se genera de la agregación
– Para asignar nombre se usa clausula as

Ejemplo: Encontrar el sueldo medio de los profesores del departamento de Informática

select avg (sueldo) as med_sueldo


from profesor
where nombre_dept = ’Informática’;

• A veces interesa mantener duplicados, por ejemplo, para avg


• Si interesa eliminar duplicados se usa clausula distinct
Agregación básica (2/2)
• Se usará la función de agregación count para contar el número de tuplas de una relación
• La notación para esta función en SQL es:
– count (atributo)
– count (*) para contar el número total de tuplas de una relación
• SQL no permite el uso de distinct con count (*)
• Se puede usar la palabra all en lugar de distinct para indicar que se mantengan los
duplicados (es opción por defecto y no es necesario)
Ejemplo: encontrar el número de tuplas en la relación asignatura
select count (*)
from asignatura;
Ejemplo: Encontrar el número total de profesores que enseñaron alguna asignatura en el
semestre de primavera de 2010
select count ( distinct ID)
from enseña
where semestre = 'Primavera' and año = 2010;
Agregación con agrupamiento (1/2)
• A veces resulta útil aplicar una función de agregación no sólo a un único conjunto de tuplas,
sino también a varios subconjuntos de tuplas; esto se especifica en SQL usando la cláusula
group by
• El atributo o atributos indicados en la cláusula group by se usan para formar grupos
• Las tuplas con el mismo valor en todos los atributos en la cláusula group by se sitúan en un
grupo

Ejemplo: Encontrar el sueldo medio de cada departamento


select nombre_dept, avg (sueldo) as med_sueldo
from profesor
group by nombre_dept;
Agregación con agrupamiento (2/2)
Ejemplo: Encontrar el número de profesores de cada departamento que enseñó una asignatura
en el semestre de primavera de 2010
select nombre_dept, count ( distinct ID) as prof_cuenta
from profesor natural join enseña
where semestre = 'Primavera' and año = 2010
group by nombre_dept;

• Cuando una consulta de SQL utilice agrupamientos es importante asegurarse de que sólo los
atributos que aparecen en la sentencia select sin agregarse se encuentran en la cláusula group
by.
Ejemplo: consulta errónea por atributo ID en select y no en group by
select nombre_dept, ID, avg (sueldo)
from profesor
group by nombre_dept;
Funciones de agregación – Clausula having (1/3)
• Hay veces que es útil indicar una condición que se aplica a grupos y no a tuplas
• SQL aplica los predicados de la cláusula having después de haber hecho los agrupamientos,
por lo que se pueden utilizar las funciones de agregación.

Ejemplo: Encontrar el sueldo medio de cada departamento pero solo de aquellos


departamentos cuyo sueldo medio sea >42.000€
select nombre_dept, avg (sueldo) as med_sueldo
from profesor
group by nombre_dept
having avg (sueldo) > 42000;

• Cualquier atributo que se encuentre en la cláusula having sin haber estado agregado tiene
que aparecer en la cláusula group by, en otro caso la consulta se trata como errónea.
Funciones de agregación – Clausula having (2/3)
• El significado de una consulta que tenga cláusulas de agregación, group by o having se define
de acuerdo a la siguiente secuencia de operaciones:
1. Como en el caso de las consultas sin agregación, la cláusula from se evalúa en primer
lugar para obtener una relación.
2. Si existe una cláusula where, el predicado de la cláusula where se aplica al resultado de
la relación de la cláusula from.
3. Las tuplas que satisfagan el predicado where se sitúan en grupos de acuerdo con la
cláusula group by, si existe. Si la cláusula group by no existe, todo el conjunto de tuplas
que satisfagan el predicado where se trata como si fuese un único grupo.
4. Se aplica la cláusula having, si existe, a cada uno de los grupos; los grupos que no
satisfagan el predicado de la cláusula having se eliminan (no son parte del resultado de la
consulta)
5. La cláusula select utiliza el resto de grupos para generar tuplas con el resultado de la
consulta aplicando las funciones de agregación para obtener una única tupla resultado
para cada grupo.
Funciones de agregación – Clausula having (3/3)
Ejemplo: Para cada sección de asignatura que se ofreció en 2009, encontrar el promedio de
créditos totales (tot_créditos) de todos los estudiantes matriculados en la sección, si la sección
tuvo al menos dos estudiantes
select asignatura_id, semestre, año, secc_id, avg (tot_creditos)
from matricula natural join estudiante
where año = 2009
group by asignatura_id, semestre, año, secc_id
having count (ID) >= 2;

– Fíjese en que toda la información necesaria para la consulta anterior se encuentra


disponible en las relaciones matricula y estudiante, y aunque la consulta se refiere a
secciones, no es necesaria la unión con sección
Agregación con valores nulos y valores boléanos
• Cuando existen valores nulos, el proceso de las operaciones de agregación se complica

Ejemplo: select sum (sueldo) from profesor; y existen valores nulos en el atributo sueldo

• Todas las funciones de agregación excepto count (*) deben ignorar los valores null

• ¿Qué ocurre si la colección sólo tiene valores null?


– count devuelve valor 0
– Todas las demás funciones agregadas devuelven null
Subconsultas anidadas
• SQL proporciona mecanismos para anidar consultas
• Una subconsulta es una expresión select-from-where que está anidada a otra consulta
• La subconsultas se usan para:
– Comprobar pertenencia de tuplas a una relación
– Comparar conjuntos
– Comprobación de relaciones vacías
– Comprobación de la existencia de tuplas duplicadas
• Concepto de subconsulta:
– Una expresión select-from-where devuelve una relación o valor
– Se puede insertar en otra expresión select-from-where en cualquier parte en la que
pueda aparecer una relación o un valor
Subconsultas anidadas – Pertenencia a conjuntos
• SQL permite comprobar la pertenencia de las tuplas a una relación.
– La conectiva in comprueba la pertenencia a un conjunto, donde el conjunto es la colección de
valores resultado de una cláusula select
– La conectiva not in comprueba la no pertenencia a un conjunto.

Ejemplo: Encontrar todas las asignaturas que se enseñaron en los semestres de otoño de 2009 y
primavera de 2010
– Anteriormente resuelto como intersección de conjuntos
– Ahora: determinar todas las asignaturas que se enseñaron en otoño de 2009 y son miembros del
conjunto de asignaturas que se enseñaron en primavera de 2010
select distinct asignatura_id
from sección
where semestre = 'Otoño' and año = 2009 and
asignatura_id in (select asignatura_id
from sección
where semestre = 'Primavera’ and año = 2010);
Subconsultas anidadas – Pertenencia a conjuntos
• Los operadores in y not in se pueden usar sobre conjuntos enumerados
Ejemplo: nombres de los profesores que no son ”Mozart” ni “Einstein”
select distinct nombre
from profesor
where nombre not in ('Mozart', 'Einstein);
• También es posible comprobar la pertenencia para cualquier relación arbitraria de SQL.
Ejemplo: encontrar el número total de estudiantes (diferentes) que hayan cursado secciones
de asignaturas en las que haya enseñado el profesor con ID 10101
select count ( distinct ID)
matricula(ID, asignatura_id, secc_id, semestre, año, nota)
from matricula enseña(ID, asignatura_id, secc_id, semestre, año)
• enseña.ID es clave externa de profesor.ID
where (asignatura_id, secc_id, semestre, año) • matricula.ID es clave externa de alumno.ID
in (select asignatura_id, secc_id, semestre, año
from enseña
where enseña.ID = 10101);
Subconsultas anidadas – Comparación conjuntos
• Para comparar conjuntos se usan constructores some y all
– < some, <= some, >= some, = some y <> some
• = some es idéntico a in, <>some no es lo mismo que not in
– < all, <= all, >= all, = all y <> all
• <> all es idéntico a not in, = all no es lo mismo que in

Ejemplo: Encontrar los nombres de todos los profesores cuyo sueldo es mayor que al menos
uno de los profesores del departamento de Biología.
select nombre
Conjunto de todos los valores de
from profesor sueldo de todos los profesores
where sueldo > some (select sueldo del departamento de Biología

from profesor
where nombre_dept = 'Biología');
Subconsultas anidadas – Comparación conjuntos
• Definición de la clausula some
F <comp> some r Û $ t Î r tal que (F <comp> t )
Donde <comp> puede ser: <, £, >, =, ¹

0
(5 < some 5 )= (Leer: 5 < que alguna tupla en la
true relación)
6
(5 < some 0 ) = false
5
(5 = some 0 ) = true
5

(5 ¹ some
0 ) = true (ya que 0 ¹ 5)
5
Subconsultas anidadas – Comparación conjuntos
• Definición de la clausula all
F <comp> all r Û " t Î r (F <comp> t)
Donde <comp> puede ser: <, £, >, =, ¹
0
(5 < all 5 ) = false (Leer: 5 < que todas las tuplas en la relación)

(5 < all 6 ) = true


10
(5 = all
4 ) = false
5

(5 ¹ all 4 ) = true (Ya que 5 ¹ 4 y 5 ¹ 6)


6
Subconsultas anidadas – Comparación conjuntos
Ejemplo: Encontrar los nombres de todos los profesores que tienen un valor de sueldo mayor
al de cualquier profesor del departamento de Biología

select nombre
from profesor
where sueldo > all (select sueldo
from profesor
where nombre_dept = 'Biología');
Subconsultas anidadas – Comparación conjuntos
Ejemplo: Encontrar el departamento, o departamentos, que tienen los máximos sueldos
promedio

select nombre_dept
from profesor Sueldo medio de los
departamentos
group by nombre_dept
having avg (sueldo) >= all (select avg (sueldo)
from profesor
group by nombre_dept);
Subconsultas anidadas – Subconsulta de correlación
• Una subconsulta que usa un nombre de correlación de una consulta externa se denomina
subconsulta de correlación.

Subconsulta
de
correlación

• Regla de ámbito de nombres de correlación (= lenguajes programación):


– En una subconsulta es legal utilizar solo los nombres de correlación definidos en la propia
subconsulta o en cualquier consulta que la contenga.
– Si un nombre de correlación se define tanto localmente en la subconsulta, como
globalmente en una consulta que la contenga, se aplica la definición local.
Subconsultas anidadas – Comprobar relaciones vacías
• Constructores para comprobar relaciones vacías:
– exists devuelve true si su argumento subconsulta no resulta vacía
– not exists devuelve true si su argumento subconsulta resulta vacía

Ejemplo: Encontrar todas las asignaturas que se enseñaron tanto en el semestre de otoño de
2009 como en el semestre de primavera de 2010
select asignatura_id
from sección as S
where semestre = 'Otoño' and año = 2009 and
exists ( select *
from sección as T
where semestre = 'Primavera' and año = 2010
and S.asignatura_id = T.asignatura_id);
Subconsultas anidadas – Comprobar relaciones vacías
• Se puede utilizar el constructor not exists para simular la operación de contenencia de conjuntos:
– Se puede escribir “la relación A contiene a la relación B” como “not exists (B except A)”.
Ejemplo: Encontrar a todos los estudiantes que se hayan matriculado en todas las asignaturas ofertadas
por el Dpto. de Biología
select distinct S.ID, S. nombre
from estudiante as S
where not exists ( (select asignatura_id Conjunto de todas las
from asignatura asignaturas ofertadas por el
Dpto. de Biología
where nombre_dept = 'Biología')
except
(select T.asignatura_id Conjunto de asignaturas en
from matricula as T las que se ha matriculado
el alumno S.ID
where S.ID = T.ID));
– Cuando la subconsulta (B except A) esté vacía, ese alumno está matriculado en todas las
asignaturas ofertadas por del Dpto. de Biología
Subconsultas anidadas – Tuplas duplicadas
• Constructores para comprobar tuplas duplicadas:
– unique devuelve true si su argumento subconsulta no tiene tuplas duplicas
– not unique devuelve true si su argumento subconsulta tiene tuplas duplicas

• Formalmente, la evaluación de unique sobre una relación se define como falsa si y solo si la
relación contiene dos tuplas t1 y t2 tales que t1=t2.
– Como la comprobación t1=t2 es falsa, si algún campo de t1 o de t2 es nulo, o los dos, es
posible que el resultado de unique sea cierto aunque haya varias copias de una misma
tupla, siempre que al menos uno de los atributos de la tupla sea null.
Subconsultas en la clausula from (1/2)
• SQL permite que se incluya una subconsulta en la cláusula from

Ejemplo: Encontrar los salarios promedio de los profesores de aquellos departamentos en los
que el sueldo medio es superior a 42.000 €
select nombre_dept, med_sueldo
from (select nombre_dept, avg (sueldo) as med_sueldo
from profesor Relación R(nombre_dept, med_sueldo),
group by nombre_dept) con los nombres de todos los
departamentos y los correspondientes
where med_sueldo > 42000; sueldos medios de los profesores

– No hemos necesitado la clausula having


Subconsultas en la clausula from (2/2)
• Se puede dar a la relación resultado de la subconsulta un nombre, y renombrar los
atributos, utilizando la cláusula as
Ejemplo: (Igual que el anterior) Encontrar los salarios promedio de los profesores de aquellos
departamentos en los que el sueldo medio es superior a 42.000 €
select nombre_dept, sueldo_medio
from (select nombre_dept, avg (sueldo) Relación dept_medio(nombre_dept, sueldo_medio),
con los nombres de todos los departamentos y los
from profesor correspondientes sueldos medios de los profesores
group by nombre_dept)
as dept_medio (nombre_dept, sueldo_medio)
where sueldo_medio > 42000;
• La mayoría, pero no todas, las implementaciones de SQL permiten las subconsultas anidadas
de la cláusula from. Sin embargo, algunas implementaciones de SQL, especialmente Oracle,
no permiten el renombrado de la relación resultado de una cláusula from.
Subconsultas anidadas – Clausula with
• La cláusula with proporciona una forma de definir vistas temporales cuya definición sólo
está disponible para la consulta en la que aparece la cláusula o en la inmediatamente
siguiente
Ejemplo: Encontrar los departamentos con máximo presupuesto
with max_presupuesto (valor) as
(select max(presupuesto)
Vista temporal max_presupuesto
from departamento) (valor)
select presupuesto
from departamento, max_presupuesto
where departamento.presupuesto = max_presupuesto.valor;

– La cláusula with define la relación temporal max_presupuesto, que se usa en la consulta


inmediatamente siguiente.
Subconsultas escalares
• En SQL se permite escribir subconsultas en cualquier punto en el que una
expresión devuelve un valor
• Estas subconsultas se llaman subconsultas escalares
• Las subconsultas escalares pueden darse en las cláusulas select, where y having
Ejemplo: lista todos los departamentos junto con el número de profesores de cada
departamento
select nombre_dept,
Variable de correlación
(select count(*) departamento.nombre_dept
from profesor
Devuelve un
único valor where departamento.nombre_dept = profesor.nombre_dept)
as numprofesores
from departamento;
• Si la consulta no devuelve un escalar, se produce error de ejecución
Modificación de una base de datos
• Mediante SQL es posible:
– Borrar tuplas de una relación
– Añadir tuplas en una relación
– Modificar el valor de algunas tuplas de una relación
– Borrar relaciones
Modificación de una base de datos – Borrado (1/2)
• Las solicitudes de borrado se expresan casi igual que las consultas.
• Solo se pueden borrar tuplas completas
– No se pueden borrar únicamente valores de atributos concretos.
• SQL expresa los borrados mediante:
delete from r
where P;
– donde P representa un predicado y r representa una relación.
• La declaración delete busca primero todas las tuplas t en r para las que P(t) es cierto y a continuación
las borra de r
– Se evita que el borrado vaya modificando el valor de P(t) dinámicamente. Ejemplo según se van
borrando tuplas, la media cambia
delete from profesor
where sueldo < (select avg (sueldo) from profesor);
• La cláusula where se puede omitir, en cuyo caso se borran todas las tuplas de r
delete from r
Modificación de una base de datos – Borrado (2/2)
Ejemplo: Borrar todas las tuplas de la relación profesor que pertenezcan al departamento
‘Finanzas’
delete from profesor profesor(ID, nombre, nombre_dept, sueldo)
departamento(nombre_dept, edificio, presupuesto)
where nombre_dept = 'Finanzas’;

Ejemplo: Borrar todos los profesores con un sueldo entre 13.000 € y 15.000€
delete from profesor
where sueldo between 13000 and 15000;

Ejemplo: Borrar todas las tuplas en la relación profesor para las cuales los profesores estén
asociados con un departamento que se encuentra en el edificio Watson:
delete from profesor
where nombre_dept in (select nombre_dept
from departamento
where edificio = Watson');
Modificación de una base de datos – Inserción (1/2)
• Para insertar datos en una relación se especifica
– La tupla que se desea insertar o
– Se formula una consulta cuyo resultado sea el conjunto de tuplas que se desea insertar
• Inserción de una tupla: asignatura(asignatura_id, nombre_asig, nombre_dept, creditos)
insert into asignatura
values ('CCS-437', 'Bases de datos', 'lnformática', 4);
– Los valores se especifican en el mismo orden en que aparecen los atributos
correspondientes en el esquema de la relación
– Los atributos se pueden especificar en la clausula insert y usar otro orden
insert into asignatura (nombre, asignatura_id, créditos, nombre_dept)
values ('Bases de datos', 'CS-43T, 4, 'lnformática');
Modificación de una base de datos – Inserción (2/2)
• De forma más general es posible que se desee insertar las tuplas que resultan de una
consulta
Ejemplo: convertir en profesores del departamento de Música, con un sueldo de 18.000 €, a
todos los estudiantes del departamento de Música que hayan conseguido más de 144 créditos
insert into profesor
estudiante(ID, nombre, nombre_dept, tot_creditos)
select ID, nombre, nombre_dept, 18000 profesor(ID, nombre, nombre_dept, sueldo)
from estudiante
where nombre_dept = 'Música' and tot_cred > 144
• Es posible dar valores únicamente a algunos de los atributos del esquema para las tuplas
insertadas (a los atributos restantes se les asigna un valor nulo).
• Los sistemas de bases de datos tienen mecanismos de carga masiva
Modificación de una base de datos – Actualizaciones
• En determinadas situaciones puede ser deseable modificar un valor dentro de una tupla sin cambiar
todos los valores de la misma
• Para este tipo de situaciones se puede utilizar la instrucción update.
Ejemplo: Subir el sueldo un 5% a todos los profesores con sueldo inferior a 70.000€
update profesor
set sueldo = sueldo * 1.05
where sueldo < 70000;
• Para evitar conflictos, SQL primero comprueba todas las tuplas de la relación para determinar si se
deben actualizar y después realiza la actualización
Ejemplo: Subir un 5% el sueldo a los profesores por debajo del sueldo medio
update profesor
Esto modifica la media. Para
set sueldo = sueldo * 1.05 evitar problemas, SQL
calcula primero todas las
where sueldo < (select avg (sueldo) tuplas a modificar
from profesor);
Modificación de una base de datos – Actualizaciones
• SQL ofrece un constructor case que se puede utilizar para llevar a cabo instrucciones de
actualización en una única instrucción update, evitando el problema del orden de
actualización.
• La forma general de la instrucción case es la siguiente:
case
when pred1 then resultado1
when pred2 then resultado2
When predn then resultadon
else resultado0
end
Modificación de una base de datos – Actualizaciones
• Ejemplo: todos los profesores con sueldos superiores a 100.000 € reciben un 3 por ciento de
aumento, mientras que el resto recibe un 5 por ciento de incremento
update profesor
set sueldo = case
when sueldo <= 100000 then sueldo * 1.05
else sueldo * 1.03
end
• Las instrucciones case se pueden usar en cualquier lugar en el que se espere un valor.
Modificación de una base de datos – Actualizaciones
• Las subconsultas escalares también son útiles en sentencias de actualización de SQL, donde
se pueden utilizar en las cláusulas set
Ejemplo: una actualización en la que se establece el atributo tot_créditos de cada tupla
estudiante con la suma de los créditos de las asignaturas que hayan aprobado ya (calificación
ni “F” ni “null”)
update estudiante S
Para evitar que tot_creditos sea
set tot_créditos = ( null si el alumno no ha hecho
ningún crédito, sustituir
select sum(créditos) sum(creditos) por:

from matricula natural join asignatura select case


when sum(créditos) is not null
where S.ID = matricula.ID and then sum(créditos)
else 0
matricula.nota < > 'F' and end
matricula.nota is not null);
matricula(ID, asignatura_id, secc_id, semestre, año, nota)
estudiante(ID, nombre, nombre_dept, tot_creditos)
• Matricula.ID es clave externa de estudiante.ID

También podría gustarte