Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Unidad 6. SQL

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 25

Tecnicatura en Análisis y Diseño de Software

1
Escuela de Formación Profesional - UNaF

Unidad 6. SQL

Introducción
Lenguaje de Definición de datos
El modelo de datos relacional utiliza el concepto de relación, tupla y atributo, en tanto
en SQL los términos corresponden a tabla, fila y columna. En este libro tabla-relación,
tupla-fila y atributo-columna, se utilizan indistintamente.
Para administrar un modelo físico de datos, SQL presenta tres cláusulas básicas:
CREATE, DROP y ALTER. Los mismos se corresponden con crear, borrar o modificar
el esquema existente.

Crear o borrar una BD


Para generar una BD la sentencia SQL es:
CREATE DATABASE nombre_BD;
Esta sentencia genera una BD cuyo nombre se indica.
Para eliminar una BD completa la sentencia es:
DROP DATABASE nombre_BD;
La cual borra la BD: esto incluye las tablas y los datos contenidos en ellas.

Operar contra Tablas de BD


Para generar una tabla en una BD, la instrucción SQL es CREATE TABLE. El
siguiente ejemplo presenta la creación de una tabla denominada empresas.
CREATE TABLE empresas (
idempresa INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
empresa VARCHAR(100) NOT NULL,
abreviatura VARCHAR(10) NULL,
cuit VARCHAR(13) NULL,
direccion VARCHAR(100) NULL,
observaciones TEXT NULL,
PRIMARY KEY(idempresa),
UNIQUE INDEX empresas_index19108(empresa));
Para definir una tabla es necesario indicar cada uno de los atributos que la componen.
En este caso algunos de los atributos son:
 Idempresa: con dominio Integer sin signo, el atributo no puede ser nulo y el
dato es autoincremental (tal como se definiera oportunamente en el capítulo de
modelado físico).
 Empresa: con dominio String y con longitud máxima 100, no puede ser nulo.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
2
Escuela de Formación Profesional - UNaF

 Obsevaciones: dominio texto (a diferencia del String que tiene longitud máxima,
el tipo de dato texto no está limitado)
La sintaxis utilizada, si bien es ANSI, tiene similitud con la utilizada por el DBMS
MySQL. Los valores posibles para los dominios de los atributos están ligados
directamente con los productos comerciales.
Asimismo ocurre con la definición de los atributos autoincrementales.
Por último, en el ejemplo anterior, se encuentran definidos dos índices para la tabla
Empresas. Estos índices se definen asociados a la clave primaria y clave candidata
respectivamente.
El siguiente ejemplo presenta la creación de otra tabla, donde se agrega la definición
de una clave foránea.
CREATE TABLE pacientesempresas (
idpacienteempresa INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
idpaciente_os INTEGER UNSIGNED NOT NULL,
idempresa INTEGER UNSIGNED NOT NULL,
fecha_desde DATE NOT NULL,
fecha_hasta DATE NULL,
PRIMARY KEY(idpacienteempresa),
INDEX empleadosempresas_FKIndex1(idempresa),
INDEX pacientesempresas_FKIndex2(idpaciente_os),
FOREIGN KEY(idempresa)
REFERENCES empresas(idempresa)
ON DELETE RESTRICT
ON UPDATE NO ACTION,
FOREIGN KEY(idpaciente_os)
REFERENCES pacientes_os(idpaciente_os)
ON DELETE RESTRICT
ON UPDATE NO ACTION);
Se agrega aquí la definición de dos índices secundarios: empleadosempresas
y pacientesempresas. Luego se definen las claves foráneas, con las referencias a las
tablas de donde se obtiene la CP. Se indica, además, el tipo de restricción de
integridad definido: el borrado está restringido y por la modificación no se toma acción.
Para eliminar una tabla del modelo la sentencia es:
DROP TABLE nombre_tabla;
Para modificar una tabla del modelo la sentencia es:
ALTER TABLE nombre_tabla ( … ) ;

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
3
Escuela de Formación Profesional - UNaF

Esta sentencia debe indicar, además, que tipo de modificación se desea realizar sobre
la tabla. Así entre paréntesis se pueden agregar, modificar o borrar atributos, índices o
restricciones de integridad.
A modo de ejemplo, la siguiente sentencia SQL agrega el atributo razón social a la
tabla empresa generada anteriormente, se quita el atributo cuit y se modifica el
dominio del atributo dirección por un string de longitud 50.
ALTER TABLE empresas (
Add column razon_social VARCHAR(100) NOT NULL,
Drop column cuit,
Alter column direccion VARCHAR(50) NULL);

Lenguaje de Manipulación de datos


En esta sección se presenta la sintaxis y semántica asociada de SQL2 (SQL92) para
recuperar información de una BD. Además, se presentarán las sentencias básicas
para agregar, borrar o modificar información contenida en la BD.
Para desarrollar esta sección se utilizarán varios ejemplos, basados en el modelo de
datos presentado en el capítulo anterior.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
4
Escuela de Formación Profesional - UNaF

Figura 1.
Estructura Básica
La estructura básica de una consulta SQL tiene el siguiente formato:
SELECT lista_de_atributos
FROM lista_de_tablas
WHERE predicado
Donde la lista_de_atributos indica los nombres de los atributos que serán presentados
en el resultado. Estos atributos deben estar contenidos en las tablas indicadas en la
consulta. Lista_de_tablas indica las tablas de la BD necesarias para resolver la
consulta; sobre las tablas indicadas en la lista se realiza un producto cartesiano. Por
último, predicado indica que condición deben cumplir las tuplas de las tablas para
estar en el resultado final de la consulta.
Ejemplo 1: presentar todos los alumnos que figuran en la tabla Alumnos
SELECT nombre FROM alumnos

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
5
Escuela de Formación Profesional - UNaF

Se puede notar que la sentencia WHERE no es obligatoria. En este ejemplo para


presentar el nombre de todos los alumnos no es necesario aplicar ningún filtro de
tuplas. Solo se requiere proyectar al atributo deseado. La tabla temporal obtenida
como respuesta a este ejercicio, de acuerdo con los datos presentados en la figura 1
es:

Ejemplo 2: presentar todos los datos de los alumnos que figuran en la tabla alumnos.
SELECT idalumno, nombre, dni, idlocalidad, idcarrera FROM alumnos
SQL presenta un operador que permite reemplazar la escritura literal de todos los
atributos de la tabla. Este operador es el * , su aparición indica que todos los atributos
de las tablas definidas en el FROM, serán presentados en el resultado de la consulta.
El ejemplo anterior puede definirse como:
SELECT * FROM alumnos
Ambas soluciones del ejemplo 2 retornan la tabla Alumnos tal y como se presenta en
la figura 1.
Ejemplo 3: presentar todos los alumnos que cursen la carrera cuyo código es 2.
SELECT nombre FROM alumnos WHERE idcarrera = 2
En este caso es necesario utilizar la condición para filtrar en el resultado las tuplas
deseadas.

Ejemplo 4: presentar todos los alumnos que cursen la carrera cuyo código es 2 y vivan
en la localidad con código 1.
SELECT nombre
FROM alumnos
WHERE idcarrera = 2 AND idlocalidad = 1

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
6
Escuela de Formación Profesional - UNaF

En este caso es necesario utilizar la condición para filtrar en el resultado las tuplas
deseadas.

Ejemplo 5: presentar todas las materias y el año en que se cursan.


SELECT nombre, año_curso FROM materias

Ejemplo 6: mostrar todos los códigos de materias que estén en la tabla Inscripciones
que tengan al menos a un alumno aprobado.
SELECT idmateria FROM inscripciones WHERE resultado > 3
La Tabla temporal obtenida como resultado de la consulta es:

Se puede notar que el código 2 aparece varias veces en el resultado. Esto significa
que más de un alumno ha aprobado la materia cuyo código es 2. En determinadas

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
7
Escuela de Formación Profesional - UNaF

circunstancias puede no ser necesario que el mismo resultado aparezca varias veces.
Para eliminar tuplas repetidas se debe utilizar la cláusula DISTINCT.
SELECT DISTINCT idmateria
FROM inscripciones
WHERE resultado > 3
SQL define, además, el operador ALL. Este operador muestra todas las tuplas, aún las
repetidas. En caso de no poner explícitamente el operador DISTINCT, SQL asume el
operador ALL, por este motivo en general nunca se explicita.
Ejemplo 7: presentar todas las carreras que tiene entre 4 y 6 años de duración.
SELECT nombre
FROM carreras
WHERE duracion_años >= 4 AND duracion_años <= 6
Además, es posible realizar la misma consulta utilizando el operador BETWEEN. La
consulta anterior puede expresarse como:
SELECT nombre
FROM carreras
WHERE duracion_años BETWEEN 4 and 6
Los atributos utilizados en el SELECT de una consulta SQL pueden tener asociados
operaciones válidas para sus dominios.
Así, por ejemplo sería válida una consulta que devuelva el salario de un empleado
menos un 10% de retención.
SELECT nombre_empleado, salario * 0.9
FROM empleados
WHERE ocupacion = “Gerente”
Esta consulta devuelve el nombre de cada gerente y el valor correspondiente al 90 %
de su salario.
Sobre los atributos definidos en un SELECT se pueden realizar cualquiera de las
operaciones básicas definidas para su domino. Cada DBMS en particular define su
mapa de operaciones.
Hasta el momento, se presentaron consultas que solamente involucraron una tabla del
modelo de datos. Para realizar un producto cartesiano, basta con poner en la cláusula
FROM dos o más tablas.
Ejemplo 8: presentar el nombre de todos los alumnos y la carrera que cursa:
SELECT alumnos.nombre, carreras.nombre
FROM alumnos, carreras
WHERE alumnos.idcarrera = carreras.idcarrera
El resultado de la consulta se presenta en la siguiente tabla de resultados:

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
8
Escuela de Formación Profesional - UNaF

La cláusula WHERE es necesaria por el mismo motivo que el producto cartesiano


necesitó en AR (Algebra Relacional) de una selección para filtrar las tuplas con
sentido. Asimismo, en la consulta se puede observar que fue necesario definir un
prefijo para los atributos nombre e idcarrera, que se encontraban repetidos
sintácticamente en ambas tablas.
Ejemplo 9: presentar el nombre de todos los alumnos, la carrera que cursa y de que
localidad proviene:
SELECT a.nombre, c.nombre, l.nombre
FROM alumnos a, carreras c, localidades l
WHERE a.idcarrera=c.idcarrera AND a.idlocalidad=l.idlocalidad
Esta consulta es similar a la anterior, ahora a partir de tres tablas. Se puede notar que
seguido de los nombres de las tablas en la cláusula FROM, se agregó una letra. Esta
letra actúa como un alias de cada tabla. Si bien en esta consulta no es necesario
renombrar las tablas, es frecuente cambiar el nombre de la relación por otro más corto,
con el propósito de escribir más rápidamente la consulta.
De la misma forma que se puede renombrar una tabla en la cláusula FROM, es
posible renombrar un atributo en al cláusula SELECT. La siguiente consulta resuelve
nuevamente el ejemplo 9 renombrando los atributos.
SELECT a.nombre AS nombrealumno, c.nombre AS nombrecarrera,
l.nombre AS nombrelocalidad
FROM alumnos a, carreras c, localidades l
WHERE a.idcarrera=c.idcarrera AND a.idlocalidad=l.idlocalidad
Se utiliza el operador AS para renombrar un atributo. La consulta genera la siguiente
tabla.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
9
Escuela de Formación Profesional - UNaF

A partir de la cláusula básica en SQL, se han presentado las operaciones del AR


correspondientes a selección, proyección, producto cartesiano y renombrado. Las
restantes operaciones básicas (unión y diferencia) también están presente en SQL.
Ejemplo 10: presentar todas las materias aprobadas del alumno Pizarro, o rendidas
durante el 2008.
(SELECT m.nombre
FROM alumnos a, materias m, inscripciones i
WHERE a.nombre = “Pizarro” AND m.idmateria = i.idmateria AND
i.idalumno = a.idalumno AND i.resultado > 3)
UNION
(SELECT m.nombre
FROM alumnos a, materias m, inscripciones i
WHERE a.nombre = “Pizarro” AND m.idmateria = i.idmateria AND
i.idalumno = a.idalumno AND i.año = 2008)
La primera consulta devuelve los nombres de las materias rendidas por Pizarro que
resultaron aprobadas, mientras que la segunda consulta devuelve las materias
rendidas por Pizarro durante 2008. La cláusula UNION reúne ambos resultados.
En SQL92 la UNION se resuelve de manera tal que las tuplas duplicadas en ambas
subconsultas solo quedan una vez en el resultado final. Para obtener las tuplas
duplicadas se puede utilizar la cláusula UNION ALL.
La cláusula definida por SQL92 para la diferencia de conjuntos es EXCEPT, en tanto
que para la operación de intersección se utiliza la cláusula INTERSECT.

Operadores de string
Una de las características interesantes y que dotan a SQL de gran potencia en la
generación de consultas que relacionan Spring, resulta del uso del operador de
comparación LIKE.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
10
Escuela de Formación Profesional - UNaF

Cuando una cadena se compara por igualdad (=) el resultado será verdadero si ambas
cadenas son iguales, falso en caso contrario.
Suponga que se desea saber el DNI y la localidad donde nació un alumno, cuando lo
único que se recuerda del alumno es que su nombre comienza con P. Si se definiera
al condición (nombre = “P”) no retornaría ninguna tupla, dado que no hay nombre
alguno de alumno que sea solamente P.
Dicha consulta puede resolverse de la siguiente forma:
SELECT nombre, idlocalidad, dni
FROM alumnos
WHERE nombre LIKE “P%”
El resultado obtenido se muestra en la siguiente tabla.

El operador LIKE se conjuga con el carácter reservado %. Se compara el atributo


nombre de la tabla alumnos contra el string que empieza con P y continúa con
cualquier substring (ese es el comportamiento del carácter %, el cual considera válida
a partir de la posición donde aparece, cualquier cadena de caracteres, inclusive la
cadena vacía).
Entonces, cualquier tupla cuyo atributo nombre comience con P será presentado en el
resultado final.
Existe además otro carácter reservado, ‘_’, el guión bajo sustituye solo el carácter del
lugar donde aparece.
Ejemplo 11: presentar todas las materias que contengan el substring ‘ga’ dentro de su
nombre.
SELECT nombre
FROM materias
WHERE nombre LIKE “%ga%”
Se presentarán en el resultado:

El carácter reservado % indica que la cadena puede comenzar y terminar con


cualquier string, y además en algún lugar de la misma debe aparecer el substring ‘GA’

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
11
Escuela de Formación Profesional - UNaF

Ejemplo 12: presentar el nombre de los alumnos que tengan DNI que comience con 23
millones.
SELECT nombre
FROM alumnos
WHERE dni LIKE “23_ _ _ _ _ _“
Se puede notar que el atributo DNI se compara contra una cadena que comienza con
23. Luego se solicitan que aparezcan exactamente 6 caracteres más, sin importar
cuales sean.
En algunas situaciones es necesario presentar la tabla temporal que resuelve la
consulta ordenada por algún criterio. La cláusula ORDER BY permite ordenar las
tuplas resultantes por el atributo indicado.
Ejemplo 13: presentar los nombres de todas las materias y el año de curso, para la
carrera informática, ordenados por año de curso.
SELECT m.nombre, m.año_curso
FROM materias m, carreras c
WHERE c.nombre = “Informática” AND
m.idcarrera = c.idcarrera
ORDER BY año_curso
El resultado obtenido es el siguiente:

Por defecto la cláusula ORDER BY ordena las tuplas de menor a mayor, es decir en
orden creciente. Si se desea obtener el resultado ordenado de mayor a menor, hay
que utilizar el operador DESC.
Ejemplo 14: presentar los nombres de todas las materias y el año de curso, para la
carrera informática, ordenados por año de curso de mayor al menor.
SELECT m.nombre, m.año_curso
FROM materias m, carreras c
WHERE c.nombre="Informática" AND
m.idcarrera = c.idcarrera
ORDER BY año_curso DESC

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
12
Escuela de Formación Profesional - UNaF

El resultado obtenido es el siguiente:

Dentro de la cláusula ORDER BY es posible indicar más de un criterio de ordenación.


El segundo criterio se aplica en caso de empate en el primero y así sucesivamente.
Ejemplo 15: presentar los nombres de todas las materias y el año de curso, para la
carrera informática, ordenados por año de curso y nombre de la materia.
SELECT m.nombre, m.año_curso
FROM materias m, carreras c
WHERE c.nombre = "Informática" AND
m.idcarrera = c.idcarrera
ORDER BY año_curso, nombre
El resultado obtenido es el siguiente:

Consultas con funciones de agregación


Las funciones de agregación son funciones que operan sobre un conjunto de tuplas de
entrada y producen un único valor de salida. SQL define cinco funciones de
agregación (en orden alfabético):
• AVG: retorna como resultado el promedio del atributo indicado para todas las tuplas
del conjunto.
• COUNT: retorna como resultado la cantidad de tuplas involucradas en el conjunto de
entrada.
• MAX: retorna como resultado el valor más grande dentro del conjunto de tuplas para
el atributo indicado

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
13
Escuela de Formación Profesional - UNaF

• MIN: retorna como resultado el valor más pequeño dentro del conjunto de tuplas para
el atributo indicado
• SUM: retorna como resultado la suma del valor del atributo indicado para todas las
tuplas del conjunto.
Ejemplo 16: Retornar el nombre del alumno que aparece primero en una lista
alfabética.
SELECT MIN(nombre)
FROM alumnos
Este ejemplo toma como entrada todas las tuplas de alumnos. Para el atributo nombre
chequea el menor en orden alfabético y ese dato se presenta en el resultado.
Ejemplo 17: Retornar la máxima nota de alguna materia durante 2008.
SELECT MAX( resultado )
FROM inscripciones
WHERE año=2008
Aquí de la tabla inscripciones se filtran las tuplas correspondientes a 2008. Sobre ese
subconjunto se obtiene la mayor nota obtenida y se muestra como resultado. Si
hubiera varias tuplas con la misma nota esto no afecta la respuesta.
Ejemplo 18: Informar cuantos alumnos aprobaron el final de programación
SELECT COUNT(*)
FROM materias m, inscripciones i
WHERE i.idmateria=m.idmateria AND
m.nombre = “Programación” AND i.resultado > 3
En este ejemplo es necesario primero realizar un producto cartesiano entre las tablas
materias e inscripciones. En la primera se tiene definido el nombre de la materia, en la
segunda los resultados. Se filtran las tuplas con sentido del producto cartesiano,
aquellas que corresponden a Programación y que estén aprobadas. Luego la función
de agregación COUNT calcula cuantas tuplas hay en ese conjunto.
Ejemplo 19: informar cuantos alumnos aprobaron al menos un final durante 2008.
SELECT COUNT(*)
FROM inscripciones
WHERE resultado > 3 AND año = 2008
Esta consulta informa la cantidad de finales aprobados durante el 2008, sin embargo
no informa cuantos alumnos fueron los que aprobaron.
Suponga que un alumno aprobó 3 finales, entonces dicho alumno es contabilizado 3
veces, por lo tanto esta consulta no es una solución al ejercicio.
SELECT COUNT (DISTINCT *)
FROM inscripciones

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
14
Escuela de Formación Profesional - UNaF

WHERE resultado>3 AND año=2008


La segunda solución propuesta solo cuenta las tuplas diferentes. El objetivo es evitar
contar a un mismo alumno más de una vez, en caso que haya aprobado varias
materias. Nuevamente la consulta fracasa.
Tener en cuenta que el operador DISTINCT evita contar las tuplas repetidas. Pero el
conjunto en cuestión contiene tuplas con varios atributos proyectados, entre ellos el
atributo idinscripcion, que está definido como CP y por lo tanto no se repite. El
resultado obtenido por la segunda consulta es igual al obtenido con la primera y no
corresponde, aún, a la solución del ejemplo 19.
SELECT COUNT(DISTINCT idalumno)
FROM inscripciones
WHERE resultado > 3 AND año = 2008
Ahora, la consulta plantea proyectar del conjunto original solo el atributo idalumno. Así,
si un idalumno aparece varias veces, significa que ese alumno aprobó varios finales
durante 2008. Pero como solo interesa la cantidad de alumnos, el operador DISTINCT
cuenta una sola aparición en caso que haya varias. Entonces, esta última solución es
la correcta, retorna cuantos alumnos aprobaron al menos un final durante 2008.
Ejemplo 20: Informar la nota promedio (con y sin aplazos) del alumno Montezanti.
SELECT AVG(resultado)
FROM inscripciones i, alumnos a
WHERE a.nombre = "Montezanti" AND i.idalumno = a.idalumno
Tanto para la función de agregación AVG como para la función de agregación SUM el
atributo a promediar o sumar debe ser de tipo número. En su defecto, la consulta
retornará error.
Las funciones de agregación tienen una particularidad importante. Por definición estas
funciones se aplican sobre un conjunto de tuplas.
Por este motivo NO pueden estar definidas dentro de una cláusula WHERE. Intentar
utilizar una función de agregación en el WHERE significa aplicar una función aplicable
a conjuntos de una sola tupla.
Además, una función de agregación siempre retorna un resultado. No siempre es
posible retornar además de dicho resultado, el valor de otro atributo.
Ejemplo 21: retornar la carrera de mayor duración.
SELECT MAX(duracion_años), nombre FROM carreras
Esta consulta es incorrecta. La función de agregación retorna la máxima duración
encontrada para cualquier carrera en la tabla Carreras.
Suponga que en la tabla existen tres carreras con duración de 6 años y que la misma
es máxima. ¿Cual de las tres carreras retorna asociado a los 6 años de duración? Se

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
15
Escuela de Formación Profesional - UNaF

podría suponer que la consulta devuelve 3 registros. Sin embargo la función de


agregación siempre retorna un resultado. Esto plantea una incongruencia. La consulta
anterior es incorrecta, no es posible retornar ningún valor asociado a la función de
agregación. Mas adelante en este capítulo se presenta una solución para esta
consulta cuando se expliquen consultas anidadas.
Además, la siguiente sección plantea una excepción a la regla anterior.
Funciones de Agrupación
En muchos casos resulta necesario agrupar las tuplas de una consulta por algún
criterio, aplicando una función de agregación sobre cada grupo. Por ejemplo si se
quiere conocer el promedio de cada alumno que cursa informática, se deben agrupar
todos los resultados obtenidos por cada alumno de informática y sobre cada grupo
obtener un promedio. Para estas situaciones SQL prevé la cláusula GROUP BY.
SELECT a.nombre, AVG (i.resultado)
FROM inscripciones i, alumnos a
WHERE a.idalumno = i.idalumno
GROUP BY a.nombre
La cláusula GROUP BY genera n subconjuntos de tuplas, cada uno por un nombre de
alumno diferente. Luego, dentro de cada grupo se obtiene el promedio del atributo
resultado.
Se puede notar que en la cláusula SELECT se proyecta, además, el atributo nombre
del alumno. Si bien en la última parte de la sección anterior esta situación no estaba
permitida, se estableció que la regla tenía una excepción. Este es el caso, el promedio
obtenido corresponde a un subconjunto (subgrupo) de un alumno en particular. Lo que
se está proyectando junto con la nota promedio es el nombre del alumno por el cual se
generó el subgrupo. Como este nombre es único para el grupo, se proyecta un solo
nombre de alumno junto con su promedio.
Cuando se genera un agrupamiento por un criterio (atributo) es posible proyectar en el
SELECT el atributo por el cual se genera el grupo.
Hay consultas que requieren obtener resultados para grupos que satisfagan una
determinada condición. SQL prevé para esos casos la cláusula HAVING, la cual actúa
como filtro de grupos. Dentro de la cláusula HAVING es posible indicar una condición
que debe cumplir el grupo para ser tenido en cuenta.
Ejemplo 22: Presentar para cada carrera la cantidad de materias que la componen,
solo mostrar en el resultado aquellas carreras con más de 20 materias.
SELECT c.nombre, count(*)
FROM carreras c, materias m
WHERE c.idcarrera = m.idmateria

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
16
Escuela de Formación Profesional - UNaF

GROUP BY c.nombre
HAVING count(*) > 20
Se puede observar que dentro de la cláusula HAVING es posible utilizar, nuevamente,
una función de agregación. En el HAVING se controla la validez de un grupo de tuplas,
por lo tanto es posible utilizar una función de agregación. En este ejemplo la función
de agregación retorna un valor entero, por lo que es posible mediante un operador
compararlo contra un valor literal (20), el resultado será un valor booleano Verdadero o
Falso. Si se da el primer caso el grupo se presenta en el resultado final.
Ejemplo 23: presentar para cada alumno el total de veces que rindió, siempre que el
promedio de sus notas supere siete.
SELECT a.nombre, COUNT(i.idmateria)
FROM alumnos a, inscripciones i
WHERE a.idalumno = i.idalumno
GROUP BY a.nombre
HAVING AVG(i.resultado) > 7

Consultas con subconsultas


Una consulta con subconsultas, también conocidas como subconsultas anidadas,
consiste en ubicar una consulta SQL dentro de otra. Las subconsultas se pueden
utilizar en varias situaciones: 1) comprobar la pertenencia o no a un conjunto, 2)
analizar la cardinalidad de un conjunto, 3) analizar la existencia o no de elementos en
un conjunto.
SQL define operadores de comparación para subconsultas. Se analizan en esta
sección algunos de ellos.
Cuando una subconsulta retorna un único resultado, es posible compararlo contra un
valor simple. De esta forma, se puede presentar una solución a la consulta del ejemplo
21.
SELECT nombre
FROM carreras
WHERE duracion_años=(SELECT MAX(duracion_años)
FROM carreras)
La subconsulta generada retorna un único valor que se corresponde con la duración
máxima para una carrera. Luego, se compara la duración de cada carrera contra la
duración máxima. Aquella carrera en la que coincidan ambos valores será presentada
en el resultado final.
Operaciones de pertenencia a conjuntos

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
17
Escuela de Formación Profesional - UNaF

SQL define el operador IN para comprobar si un elemento es parte o no de un


conjunto.
Ejemplo 24: informar el nombre de los alumnos que están inscriptos en carreras de 5
años de duración.
Si bien este ejemplo puede resolverse utilizando conceptos ya explicados hasta el
momento, se presenta aquí otra solución viable:
SELECT nombre
FROM alumnos
WHERE idcarrera IN ( SELECT idcarrera
FROM carreras
WHERE duracion_años = 5 )
Aquí la subconsulta retorna un conjunto formado por los identificadores de carreras
correspondientes a carreras de 5 años de duración.
Para cada tupla de la tabla alumnos, se verifica si el código de carrera en la cual el
alumno está inscripto está o no definido en el conjunto obtenido. Si está en el conjunto
obtenido, el nombre del alumno es parte del resultado final debido a que se cumple la
condición preestablecida (que el alumno esté inscripto en una carrera de 5 años de
duración).
Ejemplo 25: mostrar las materias que no hayan sido aprobadas por ningún alumno.
SELECT nombre
FROM materias
WHERE idmateria NOT IN ( SELECT idmateria
FROM inscripciones
WHERE resultado > 3 )
En este caso, el operador IN está precedido por el operador booleano NOT. Para
presentar una materia, su código no debe ser parte de subconjunto generado. En el
subconjunto aparecen los códigos de todas las materias que han sido aprobadas por
algún alumno.
Operaciones de comparación contra conjuntos.
Además del operador IN, se pueden utilizar operadores de comparación de elementos
simples sobre conjuntos. Estos operadores, de funcionamiento similar a los
operadores relacionales (=, <, >, >=, <= o <>), están combinados con las palabras
reservadas SOME y ALL. Así, es posible realizar comparaciones del tipo (a modo de
ejemplo)
• =SOME, significa igual a alguno. El resultado será verdadero si el elemento simple
resulta igual a alguno de los elementos contenidos en el conjunto, falso en caso
contrario.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
18
Escuela de Formación Profesional - UNaF

• >ALL, significa mayor que todos. El resultado será verdadero si el elemento simple
resulta mayor que todos los elementos del conjunto.
• <= SOME, significa menor o igual que alguno. El resultado será verdadero si el
elemento simple resulta menor o igual que alguno de los elementos del conjunto.
Para definir algunos ejemplos adicionales se agrega al modelo original las siguientes
tablas
DOCENTES = ( iddocente, nombre, sueldo, idcarrera)
DOCENTESMATERIAS=(iddocentemateria, iddocente, idmateria, añodictado )
Que representa a los docentes, los cuales solamente pueden ser docentes de una
carrera, y las materias que dictan año por año.
Ejemplo 26: mostrar aquellos docentes que cobren un sueldo superior a algún docente
de la carrera de Quimica.
SELECT nombre
FROM docentes
WHERE sueldo >SOME ( SELECT sueldo
FROM docentes d, carreras c
WHERE d.idcarrera = c.idcarrera AND
c.nombre= “Quimica”)
Ejemplo 27: Mostrar todos los docentes con sus salarios, excepto el docente que
cobre mayor sueldo.
SELECT nombre, sueldo
FROM docentes
WHERE sueldo < SOME ( SELECT sueldo
FROM docentes )
Otra forma de resolver
SELECT nombre, sueldo
FROM docentes
WHERE sueldo < > ( SELECT MAX( sueldo )
FROM docentes )

Cláusula Exists
La cláusula EXISTS se utiliza para comprobar si una subconsulta generó o no alguna
tupla como respuesta. El resultado de la cláusula EXISTS es verdadero si la
subconsulta tiene al menos una tupla, y falso en caso contrario. No es importante para
la subconsulta el o los atributos proyectados, debido a que solamente se chequea la
existencia o no de tuplas.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
19
Escuela de Formación Profesional - UNaF

Ejemplo 28: Mostrar el nombre de los alumnos que hayan aprobado algún final durante
2007.
SELECT nombre
FROM alumnos
WHERE EXISTS ( SELECT *
FROM inscripciones
WHERE alumnos.idalumno = inscripciones.idalumno
AND resultado > 3 )
En el tabla temporal que resuelve esta consulta estará contenido el nombre de un
alumno siempre y cuando exista alguna tupla en la subconsulta. Para que la
subconsulta tenga una tupla es necesario encontrar al menos una inscripción para ese
alumno que resulte aprobada.
Ejemplo 29: mostrar aquellos alumnos que no se inscribieron en materia alguna
SELECT a.nombre
FROM alumnos a
WHERE NOT EXISTS ( SELECT *
FROM inscripciones i
WHERE a.idalumno = i.idalumno)
La subconsulta planteada devuelve para un alumno específico todas aquellas tuplas
de inscripciones que le correspondan. Sino devolviera alguna inscripción, la cláusula
NOT EXISTS en la consulta principal resulta verdadera, y por lo tanto el alumno se
presenta en la tabla resultado.
Suponga que las tablas ALUMNOS, MATERIAS, CARRERAS e INSCRIPCIONES
tiene los datos presentados en la figura 2.

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
20
Escuela de Formación Profesional - UNaF

Figura 2.
Operaciones con Valores Nulos
En SQL se debe tener especial cuidado cuando un atributo puede contener valores
nulos. En general, cuando se resuelve un algoritmo y el programador debe preguntar
si una variable tiene valor nulo genera una expresión del tipo:
Variable = ‘’
Al utilizar esta expresión, comillas sin ningún carácter en su interior se asume valor
nulo. Sin embargo este tipo de expresiones no tienen un comportamiento similar
cuando se trata de consultas SQL. Cuando un dominio de un atributo puede contener
valores nulos no puede tratarse de esta forma. Los dominios con posibles valores
nulos incorporan al conjunto de valores posibles el valor NULL. Este valor se almacena
por defecto si el usuario no define otro. Entonces, una consulta que pregunta por un
string nulo (‘’) no una respuesta satisfactoria. Para estas situaciones se define un
nuevo operador IS NULL o su negación IS NOT NULL.
Ejemplo 30: presentar todos los alumnos que no tengan definida una localidad de
procedencia.
SELECT a.nombre
FROM alumnos a
WHERE idlocalidad IS NULL

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
21
Escuela de Formación Profesional - UNaF

Productos naturales
En el capítulo anterior se presentó al producto natural como una operación adicional
del AR que permite resolver de una forma más eficiente el producto cartesiano. Hasta
el momento, en SQL se presentó al producto cartesiano como única opción para ligar
tablas.
Por las mismas cuestiones de performance planteadas en el capítulo 14 es necesario
que SQL presente una alternativa al producto cartesiano, el producto natural. Las
sentencias disponibles al efecto son: INNER JOIN, LEFT JOIN, RIGTH JOIN, FULL
JOIN. A continuación se detallan y muestran ejemplos de cada una de ellas.
Para realizar un producto natural como fue definido en el capítulo 14, debe utilizarse la
cláusula INNER JOIN.
Ejemplo 30.1: presentar todos los alumnos y su localidad de procedencia.
SELECT a.nombre, l.nombre
FROM alumnos a
INNER JOIN localidades l ON a.idlocalidad = l.idlocalidad
Nótese que en la definición del producto natural se realiza en la cláusula FROM
indicando las tablas involucradas en el producto, y luego de la sentencia ON la
condición que debe cumplirse.
El ejemplo 9 puede resolverse, ahora, de la siguiente forma
SELECT a.nombre, c.nombre, l.nombre
FROM alumnos a
INNER JOIN carreras c ON (a.idcarrera = c.idcarrera )
INNER JOIN localidades l ON (a.idlocalidad = l.idlocalidad)
Los otros productos tienen similar performance, pero su comportamiento es diferente.
Mientras que el INNER JOIN realiza un producto natural clásico, reuniendo las tuplas
de las relaciones que tienen sentido, tanto LEFT como RIGTH y FULL operan con
algunas diferencias.
Suponer:
Tabla1 LEFT JOIN Tabla2
En primera instancia se reúne cada tupla de la tabla 1 con su correspondiente tupla en
la tabla2, similar al INNER JOIN. Luego, si alguna tupla de la tabla 1 no se reúne con
una tupla de la tabla 2, igualmente aparece en el resultado, con los atributos de la
tabla 2 con valor nulo.
Ejemplo 31: presentar cada carrera con sus materias.
SELECT c.nombre, m.nombre
FROM carreras c
LEFT JOIN materias m ON (m.idcarrera = c.idcarrera)

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
22
Escuela de Formación Profesional - UNaF

Si se utiliza la figura 2 como contenido de las tablas carreras y materias el resultado


final será:

Las restantes cláusulas operan de manera similar.


RIGTH JOIN genera, primero, un INNER JOIN para luego completar con las tuplas de
la tabla 2 que no tienen correspondencia en la tabla 1. Se puede notar, entonces, que
las siguientes expresiones resultan equivalentes:
Tabla1 LEFT JOIN tabla2
Tabla2 RIGHT JOIN tabla1
Por último, FULL JOIN, genera el equivalente a un INNER JOIN, LEFT JOIN y RIGTH
JOIN en conjunto. Es decir, reúne las tuplas con sentido, luego agrega las tuplas de
las tablas 1 sin correspondencia en la tabla 2 y, por último, reúne las tuplas de tabla2
sin correspondencia en tabla1.
Algunos sistemas de gestión de bases de datos soportan el FULL JOIN.

Otras operaciones: Insertar, Borrar y Modificar


Hasta el momento se discutieron y ejemplificaron alternativas, las más comunes y
utilizadas, para realizar consultas sobre una BD. Como se indicó anteriormente en este
libro, el 80% de las operaciones que se realizan en una BD son de consulta. Sin
embargo, las restantes tres operaciones también son necesarias: agregar, borrar y/o
modificar la información.
Insertar tuplas a la BD
La cláusula utilizada para agregar tuplas a una tabla es la cláusula INSERT INTO. El
siguiente representa un ejemplo de inserción de una tupla a la tabla ALUMNOS.
INSERT INTO alumnos (nombre, dni, idlocalidad, idcarrera )
VALUES ('Julio Cesar', '12344321', 3, 1)
Se puede observar que se indican cuatro de los cinco atributos que componen la tabla
alumnos. El atributo idalumno está definido como autoincremental. Por este motivo,
será el DBMS el encargado de asignarle el valor correspondiente. Si el usuario

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
23
Escuela de Formación Profesional - UNaF

intentara asignar un valor a un atributo definido como autoincremental, la operación de


inserción falla.
Se debe tener cuidado, además, con los dos últimos atributos dado que representan
claves foráneas. En caso de haber exigido integridad referencial estricta, se debe
indicar identificadores válidos. Esto significa que el número 3 correspondiente a
idlocalidad debería tener su correlato en la tabla localidades, y en forma análoga en
número 1 debe existir en la tabla de carreras. En su defecto, nuevamente la consulta
falla.
La cláusula INSERT INTO genera una sola tupla cada vez que es ejecutada.
Borrar tuplas de la BD
Para borrar una tupla o un conjunto de tuplas de una tabla se utiliza la cláusula
DELETE FROM
Ejemplo 32: borrar todos los alumnos de la localidad de La Plata.
DELETE FROM alumnos
WHERE idlocalidad = (SELECT idlocalidad
FROM localidades
WHERE nombre = “La Plata”)
Si la cláusula definida fuera
DELETE FROM alumnos
Se borran todas las tuplas definidas en alumnos.
Por último, debe notarse que nuevamente la integridad referencial tendrá especial
énfasis sobre la cláusula DELETE. Esto es, solamente pueden ser borradas de la tabla
aquellas tuplas que cumplan las condiciones de integridad referencial definidas.
Modificar tuplas de la BD
Por último, la cláusula UPDATE … SET se utiliza para modificar el contenido de uno o
varios atributos de una tabla.
Ejemplo 33: modificar la duración de la carrera Contador, llevándola a cinco años.
UPDATE carreras
SET duracion_años = 5
WHERE nombre = “Contador”
Se debe tener en cuenta que si varias tuplas cumplen la condición estipulada en el
WHERE, todas ellas serán modificadas. El siguiente ejemplo muestra como se
incrementaría el salario de los empleados en un 20%
UPDATE empleados
SET salario = salario * 1.2

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
24
Escuela de Formación Profesional - UNaF

Creación de Índice
La creación de un índice se hace a través de una sentencia CREATE INDEX, que
permite nombrar al índice. Supongamos que ya se tiene una tabla definida y las
consultas de búsqueda son muy lentas. Los índices pueden mejorar en gran medida el
rendimiento del sistema creando INDEX en la columna más utilizada en la cláusula
WHERE.
CREATE INDEX index_name
ON table_name (column_names)
Se puede agregar también un índice a una tabla existente con la siguiente sentencia:
ALTER TABLE name_tabla ADD INDEX(name);
Eliminación de Índice
La instrucción DROP INDEX seguida del nombre del índice permite eliminar el índice
en cuestión.
DROP INDEX index_id ON table_name
También:
ALTER TABLE table_name DROP INDEX index_name

Tipos de índices en MySQL:


PRIMARY: Permite crear índices de un único valor sobre una columna, Este tipo de
índices permite crear en una sola columna por cada tabla y no permite valores nulos.
INDEX: Permite crear índices sobre una o varias columnas que compartan el índice;
este tipo de índice no aplica ninguna característica especial, simplemente mejora el
tiempo de ejecución de la consulta.
UNIQUE: Permite crear índices de un único valor por columna (la columna no admite
valores duplicados), es similar al índice PRIMARY con la diferencia de que una tabla
puede tener más de un índice UNIQUE.
FULLTEXT: Permite crear índices para realizar búsquedas por palabras que están
contenidas en un texto de una columna, este tipo de índice se aplica a columnas de
tipo CHAR, VARCHAR y TEXT.
SPATIAL: Permite crear índices sobre datos geométricos para búsquedas que
correspondan sólo a este tipo de dato. Solo está disponible para algunas bases de
datos.

Operadores de comparación
Los operadores de comparación que se pueden utilizar en la cláusula WHERE son:

Base de Datos Lic. Cardozo Claudio Andrés


Tecnicatura en Análisis y Diseño de Software
25
Escuela de Formación Profesional - UNaF

Operador Significado
> Mayor que
< Menor que
>= Mayor igual que
<= Menor igual que
= Igual
<> Distinto
!= Distinto
Operadores lógicos
Operador Significado
Devuelve verdadero si las expresiones a su izquierda y
AND derecha son ambas verdaderas.
Devuelve verdadero si cualquiera de las dos expresiones
OR a izquierda y derecha del OR, son verdaderas.
Invierte la lógica de la expresión que esta a su derecha. Si
NOT era verdadera, mediante NOT pasa a ser falso.
Funciones para redondear el número de decimales
Función Descripción
ROUND(n,decimales) Redondea el número al siguiente
número con el número de decimales
indicado más cercano.
ROUND(8.239,2) devuelve 8.24
TRUNC(n,decimales) Los decimales del número se cortan
para que sólo aparezca en número de
decimales indicado.

Bibliografía:

Bertone, Rafael; Thomas, Pablo. Introducción a las bases de datos. Fundamentos y diseño. 1a.
Ed. Prentice Hall - Pearson Education, 2011.
IES Luis Vélez de Guevara. Departamento de Informática. Gestión de bases de datos v1.0, 2019

Base de Datos Lic. Cardozo Claudio Andrés

También podría gustarte