Está en la página 1de 100

CURSO DE INTRODUCCIÓN A BASES DE DATOS

LUIS ICHAICOTO BONCANCA

Rev.: 01, 25-Enero-2021

PORTADA
CURSO DE INTRODUCCIÓN A BASES DE DATOS
Profesor: LUIS ICHAICOTO BONCANCA

Rev.: 01, 25-Enero-2021

TEMA 1: INTRODUCCION A LOS SISTEMAS


DE BASES DE DATOS

PORTADA
1. INTRODUCCION
En este curso aprenderemos sobre las bases de datos y la utilización de los sistemas de gestión de
bases de datos, principalmente desde los puntos de vista de usuario, diseñador y desarrollador de
aplicaciones de bases de datos. Muchas aplicaciones, hacen uso de bases de datos para funcionar,
estas bases de datos están disponibles para las aplicaciones que las utilizan gracias a un sistema de
gestión de bases de datos.

En la actualidad, los sistemas de gestión de bases de datos son bastante populares, podemos
encontrarlos virtualmente en todas partes: Están detrás de muchos sitios web, en sistemas de gestión
bancaria, sistemas de telecomunicación, experimentos científicos, explotación de redes de sensores,
etc.

1.1 ¿Qué proporciona un sistema de gestión de bases de datos?

Principalmente, proporciona los medios necesarios para manejar o manipular enormes cantidades de
datos o información. Una definición más detallada es la siguiente:

Proporciona el acceso multi-usuario a, y el almacenamiento de enormes cantidades de datos


persistentes de una forma eficiente, fiable y conveniente.

Expliquemos los aspectos relevantes que hacen tan populares a estos sistemas:

 Volumen de datos: Las bases de datos manejan enormes cantidades de datos actualmente,
del orden de los terabytes, en muchos casos se trata de terabytes de datos diarios. El detalle
crítico respecto a este volumen elevado, es que generalmente los sistemas de gestión de bases
de datos, manejan volúmenes de datos superiores a la capacidad de memoria de los sistemas
computacionales habituales, es decir, aunque las capacidades de memoria para la ejecución de
aplicaciones crecen de forma rápida, el volumen de datos que deben gestionar las bases de
datos crece a un ritmo mucho más rápido. Por tanto, los SGBD están diseñados para manejar
datos ubicados fuera de la memoria principal de los sistemas computacionales.
 Persistencia: Los datos manejados por un SGBD, se dice normalmente que son persistentes, es
decir, el ciclo de vida de los datos almacenados en la BD es mucho mayor que el ciclo de vida
de los programas que acceden a los datos en un determinado momento.

Recordarles que los programas al ser ejecutados, se cargan en memoria, se crean variables y se
manipulan datos cargados en memoria. Una vez se termina el procesamiento de datos y
presentación de resultados, el programa finaliza y desaparece de la memoria así como los
datos; todo lo contrario para los SGBD, donde lo que permanece son los datos, los programas
se inician, operan sobre los datos de la BD, finalizan su sesión y los datos siguen en la BD; a
menudo se da el caso de que multiples programas operan sobre los mismos datos de la BD.

 Seguridad: Puesto que los SGBD manejan información crítica como pueden ser de los sistemas
de telecomunicación o los sistemas bancarios, deben existir mecanismos que garanticen la
existencia consistente de los datos manejados por el SG, mecanismos que eviten la pérdida o
sobre escritura de los datos ante fallas o averías como: fallos de hardware, software, apagones
eléctricos (sería catastrófico si el saldo se su cuenta bancaria se modificara como consecuencia
3

de un apagón); incluso ante los ataques de usuarios maliciosos que traten de corromper los
Página

datos.
 Multi-usuario: Hemos mencionado la situación en que varios programas pueden operar sobre
la misma BD; En el caso de un solo programa operando sobre los datos, es posible que dicho
programa permita el acceso simultáneo o concurrente a más de un usuario. Cuando se da este
caso de acceso de multiples aplicaciones a los mismo datos, el sistema debe contar con
mecanismos que garanticen la consistencia de dichos datos ante esta situación; por ejemplo,
el sistema debe prevenir situaciones como la posibilidad de que parte de un dato sea
modificado por un usuario y la otra parte por otro usuario.

Los mecanismos que aseguran la consistencia en este caso se denominan de control de


concurrencia. Se encargan de controlar el acceso de los usuarios a los datos de una forma
altamente eficiente, no vale restringir el acceso a n-1 usuarios mientras haya un usuario operando
sobre los datos—una solución así, reduciría considerablemente el rendimiento de la BD.

Estos mecanismos ejercen un control a nivel de los elementos atómicos de los datos en la BD, de
manera que varios usuarios pueden estar operando en la misma base de datos, pero no actúan
sobre los mismos elementos de datos (tablas, atributos, tuplas, etc.)

 Conveniencia: Una de las características críticas en el diseño de los SGBD. Se deben diseñar de
manera que hagan muy fácil la operación con enormes cantidades de datos, que permitan un
procesamiento interesante y potente de los datos almacenados, esto ocurre en dos niveles:
o Independencia física de los datos: Quiere decir, que en disco (dispositivo de
almacenamiento masivo o secundario), los datos están distribuidos y estructurados de
una forma determinada, que es diferente e independiente de la forma en que los
programas conciben la estructura de los datos. Esto permite que se pueda cambiar la
estructura física de los datos, sin necesidad de cambiar el programa que accede a los
datos, lo que significa, las operaciones sobre los datos son independientes de la
estructura y distribución de los datos en disco.
o Lenguajes de consulta de alto nivel: Normalmente las consultas a SGBD se suelen
hacer con lenguajes relativamente compactos, que describen a muy alto nivel (muy
próximo al idioma en que nos expresamos), la información que se quiere de la BD;
concretamente, se rigen por el concepto de declarativo, quiere decir que en un
lenguaje de consulta, solo hay que centrarse en expresar o decir lo que se quiere de
la base de datos y no pensar en la formulación del algoritmo capaz de extraer dicha
información de la BD. Esta es una característica muy importante, ya que nos permite
formular fácilmente las consultas, sabiendo que el propio sistema se encargará de
determinar el algoritmo más apropiado para extraer los datos de forma eficiente.
 Eficiencia: Existe un dicho en el sector inmobiliario que dice: Cuando eres dueño de una
propiedad, los tres aspectos más importantes dela misma, son la ubicación de la propiedad,
la ubicación y la ubicación; en el mundo de las bases de datos, se aplica un dicho similar, que
dice: Los tres aspectos más importantes en un SGBD son: primero, el rendimiento, segundo,
el rendimiento y tercero, el rendimiento.
Los sistemas reales de bases de datos, deben realizar miles de consultas/actualizaciones por
segundo y no necesariamente se trata de consultas elementales, suelen ser en muchos casos,
operaciones muy complejas; por tanto construir un SGBD capaz de ejecutar consultas,
consultas complejas a este ritmo sobre una enorme cantidad de datos (terabytes de datos), no
4

es tarea fácil, y esa es otra de las características principales que debe reunir un buen sistema
Página

de gestión de bases de datos.


 Fiabilidad: Finalmente, igualmente importante que los características anteriormente descritas,
está la fiabilidad. Un buen sistema de gestión de bases de datos SGBD, debe garantizar la
disponibilidad de los datos el mayor tiempo posible. Claramente los sistemas de
telecomunicación y los sistemas bancarios son sistemas que requieren una disponibilidad
permanente. Por eso los SGBD buenos ofrecen garantías del 99.999% de fiabilidad.

Bueno, todas estas características descritas, nos deben dar una idea de la importancia y la
responsabilidad de los SGBD. De modo que deberíamos estar convencidos de la importancia de todas
estas características, si diseñamos aplicaciones que vayan a utilizar bases de datos.

1.2 Otros aspectos relacionados con el mundo de las bases de datos

 Uso de frameworks para desarrollo de aplicaciones de bases de datos: Los frameworks son
entornos que facilitan el desarrollo de aplicaciones y traen integradas las funciones necesarias
para ayudarnos a establecer las conexiones a las bases de datos, de modo que nuestra
aplicación pueda lanzar consultas a la base de datos sobre la que debe operar. Algunos
frameworks populares son Ruby-on-rails, Django, etc. No vamos a tratar el uso de frameworks
en este curso, más bien nos centraremos en el mismo sistema de base de datos, en cómo se
utiliza y que nos proporciona.
 Uso de “middleware”: A menudo los SGBD se utilizan conjuntamente con determinadas
aplicaciones conocidas por ese nombre. El software middleware facilita la interacción de las
aplicaciones con el SGBD de distintas formas. Algunos ejemplos de este tipo de software son,
los servidores de aplicaciones, servidores web, etc. En este curso tampoco se tratará este
tema.
 El uso intensivo de datos por una aplicación, no implica la existencia de un SGBD asociado:
No es cierto que toda aplicación que hace un uso intensivo de datos, necesariamente utiliza un
SGBD; Históricamente, se han utilizado archivos para el almacenamiento de gran cantidad de
datos, aunque actualmente esta práctica ha quedado en desuso, pero hay una gran cantidad
de información por allí disponible en archivos o ficheros; por ejemplo en hojas de cálculo
Excel, y resultan útiles de alguna manera; el procesamiento de datos no siempre se realiza
mediante consultas asociadas a SGBD, un ejemplo es el software hadoop, que es un
framework de procesamiento para ejecutar operaciones sobre información almacenada en
ficheros o archivos.

Este curso se centra en torno a los SGBD propiamente dichos y en como almacenar y operar sobre
los datos a través de un SGBD.

1.3 CONCEPTOS FUNDAMENTALES

 MODELO DE DATOS: Es la descripción general de cómo están estructurados los datos, nos dice
la forma general que tendrán los datos en la BD. Uno de los más populares es el modelo
relacional, del que hablaremos bastante; en el modelo relacional, los datos se almacenan
como un conjunto de registros o filas.

Otra alternativa popular para almacenar datos (otro modelo de datos) es mediante el formato XML, el
formato XML representa los datos mediante una estructura jerárquica de valores etiquetados.
También se puede almacenar datos mediante grafos, con lo cual los datos en la BD se almacenan en
5

forma de nodos y aristas.


Página
 ESQUEMA vs DATOS

El concepto de esquema y dato se puede comparar con los conceptos “tipo de datos” y “variables”
utilizados en los lenguajes de programación.

El esquema establece o determina la estructura de la base de datos, por ejemplo, si vamos a


almacenar información sobre estudiantes, podemos almacenar la identidad, la calificación; o
información sobre universidades (nombre de la universidad, provincia donde se ubica, etc.) pues el
esquema nos define la estructura de la BD, esos atributos que decidimos almacenar sobre estudiantes
y universidades, conformarían el esquema; mientras que los datos serían la información realmente
almacenada, por ejemplo, información de un alumno concreto(Nombre=Juan, calificación=8,5),
tenemos que Esquema = estudiantes(Nombre, calificación), datos=(Juan, 8,5).

En un lenguaje de programación definimos tipos de datos para diferentes variables de manera que la
variable solo puede soportar valores que se ajustan al tipo de datos definido, mientras que durante la
ejecución, el valor de la variable puede quedar modificado de un momento a otro, siempre por un
valor del mismo tipo; De forma análoga, en las bases de datos, definimos un esquema y luego
almacenamos un montón de datos que se deben ajustar a dicho esquema.

Por lo general, el esquema de una BD se define al principio de su creación, y apenas se modifica con el
tiempo, pero sin embargo, los datos si cambian bastante a lo largo del tiempo.

 LENGUAJE DE DEFINICION DE DATOS (LDD)


Es el lenguaje utilizado para establecer o crear esquemas o estructuras para bases de datos. En
la práctica, los diseñadores utilizan herramientas de alto nivel que les permiten visualizar la
estructura que desean crear y luego finalmente la implementan mediante el LDD.
 LENGUAJE DE MANIPULACION DE DATOS (LMD)

Una vez creado el esquema de la BD, y tras cargar datos a la misma, es cuando se puede utilizar el
LMD. Es el lenguaje utilizado para realizar consultas y modificaciones a los datos de la BD.

1.4 PERSONAL IMPLICADO EN EL DESARROLLO Y EXPLOTACIÓN DE SISTEMAS DE BASES DE DATOS

 Implementador (del SGBD): Es el responsable de la construcción del sistema, transforma el


diseño en un software de gestión de bases de datos con todas las características definidas para
tal sistema. En este curso, no nos enfocaremos en esta función, trataremos más las funciones
subsiguientes.
 Diseñador (de base de datos): Es responsable de crear el esquema de la base de datos.
Partiendo de la necesidad de diseñar una aplicación, el diseñador identifica la necesidad de
una base de datos, a través de la especificación de requisitos de la aplicación; en este
momento, el diseñador debe estudiar los datos y pensar en la mejor forma de estructurar los
datos antes de crear la aplicación. Esta tarea puede resultar bastante difícil cuando nos
encontramos ante datos muy complejos.
 Desarrollador (de aplicaciones para base de datos): Obviamente se trata de un programador,
responsable de crear la o las aplicación/es que van a interactuar u operar sobre la BD, a
menudo sirviendo de interfaz entre el usuario final y los datos; cabe mencionar que varias
aplicaciones pueden operar sobre una misma base de datos, por ejemplo, en una base de
6

datos de ventas, puede haber algunas aplicaciones que operan sobre la BD insertando la
Página

información de ventas conforme se van produciendo las ventas, y otras aplicaciones podrían
operar sobre la BD analizando las ventas. Por lo tanto no necesariamente habrá un
acoplamiento 1-a-1 entre bases de datos y aplicaciones.

 Administrador (de base de datos): Es la responsable de cargar o ingresar datos a la BD y de


poner el sistema en marcha, así como de mantenerlo en marcha sin incidencias; este resulta
ser un trabajo muy importante cuando se trata de importantes aplicaciones de bases de datos,
ya que para bien o para mal, los sistemas de bases de datos tienden a incorporar un número
determinado de parámetros de ajuste, tal que, el ajuste óptimo de dichos parámetros, marca
una diferencia notable en el rendimiento del sistema. Por lo que, los administradores son
personal altamente valorado, de hecho están muy bien pagados, y en grandes proyectos de
explotación, suelen ser personal clave en todo el proceso.

2. EL MODELO RELACIONAL

El modelo relacional existe desde hace más de treinta y cinco años y es en realidad, la base
fundamental de los sistemas de bases de datos. Marcó el inicio de una gran industria multimillonaria.
Entre sus características principales, destacan:

 Es utilizado en la mayoría de los sistema de bases de datos comerciales en la actualidad


 Un modelo muy simple: Se trata de un modelo extremadamente simple, esta simplicidad es
una de sus ventajas.
 Sus consultas (Query) se hacen con lenguajes de alto nivel: Consultar implica formular
preguntas a la base de datos. Los lenguajes de alto nivel son simples y bastante expresivos a la
hora de formular preguntas sobre una base de datos.
 Implementaciones eficientes: Una característica muy importante, tanto las implementaciones
del modelo, como de sus lenguajes de consulta, han alcanzado elevados niveles de eficiencia
en la implementación.

 Bloques constructivos del modelo relacional


 La relación (o tabla): El principal bloque constructivo en una base de datos relacional, es la
relación o tabla. Por tanto, en el modelo relacional, una base de datos se define como un
conjunto de relaciones (tablas) con nombres asignados. El nombre de una relación se deduce a
partir de la temática de la información que se quiere almacenar en dicha tabla. Como
sabemos, una tabla es un conjunto de filas y columnas. Por ejemplo, supongamos dos
relaciones con los nombres estudiantes y universidades:
estudiante universidad

 Atributos: Forman parte de las relaciones, cada relación o tabla consta de un número
predefinido de atributos con nombre asignado. Cada atributo es una columna de la tabla;
podemos entender los atributos como los datos informativos que queremos almacenar sobre
un tema concreto (el nombre de la tabla).
7
Página
Continuando con nuestro ejemplo de estudiante y universidad, podemos crear como atributos para
estudiantes: identidad del estudiante (eID), su nombre (enombre), su calificación (calificación) y la foto
del estudiante (foto); para la tabla universidad, el nombre de la universidad (unombre), la provincia
donde se encuentra (provincia) y el precio de matrícula (matricula). Entonces las tablas quedarían de la
siguiente forma:

estudiante
eid enombre calificacion foto Constituyen la estructura de las
tablas, los datos reales estarán en
lo que llamaremos tuplas o filas de
la tabla. Justo del encabezado que
universidad
contiene los nombres de atributos.
unombre provincia matricula
En el estado actual, las tablas
están vacías (no contienen ningún
dato real).

estudiante
eid enombre calificacion foto En el estado actual, las tablas
123 Obiang Belobe 7,7 están pobladas (contienen
234 Bindang Bakale 6,5 información real). En una base de
datos real, habrá millares de filas,
cada una con un valor en cada
universidad
unombre provincia matricula atributo.
UNGE BN 50000
SIPACO BS 30000
ATENEO LT 60000

 Tipo (dominio): Cada atributo de una tabla tiene un tipo de datos asignado, lo que determina
su dominio o los valores que pueden ser almacenados en su lugar correspondiente de la fila.
Por ejemplo, la identidad de un alumno, será un número entero (en Guinea Ecuatorial, no
utilizamos letras ni decimales en el número de identificación), el nombre será de tipo texto, la
calificación será de tipo número decimal (coma flotante o float), etc.; para la universidad,
tendríamos el nombre y la provincia como texto y la matricula como un valor numérico (puede
ser decimal o entero).
 Esquema (o estructura): El esquema de una base de datos es la estructura de sus relaciones o
tablas, es decir, es la descripción estructural de las tablas de la base de datos, incluye el
nombre de las relaciones, el nombre de los atributos de cada relación y los tipos de datos de
estos atributos.
 Instancia: La instancia de una base de datos, se refiere al contenido real de la base de datos en
un instante determinado. Por lo general, el esquema se establece a priori, en el momento
inicial, mientras que las instancias de la BD, tienden a cambiar a lo largo del tiempo.
 NULL (NULO): Ya sabemos que cada atributo tiene un tipo de datos definido. Pero existe el
tipo null o nulo disponible para cualquier atributo de una tabla. Los valores nulos se utilizan
para indicar que el valor de un atributo concreto puede ser “desconocido” ó “indefinido”. Por
8
Página

ejemplo:
Nos dan la siguiente información acerca de un estudiante que hay que registrar en la base de datos,
id=345, nombre= Bilogo Mba, calificación = (No nos han dado la calificación del estudiante) y foto=
archivo JPG.

Si en la base de datos no se ha establecido ninguna restricción sobre el atributo calificación, podremos


ingresar la información anterior rellenando solo los atributos cuya información tenemos disponible. Y
el sistema se encargará de aplicar el valor nulo o null al atributo calificación, a que por alguna razón
que desconocemos, el alumno no ha proporcionado dicha información.

Por otra parte puede que Bindang Bakale no entregase su foto a la hora de inscribirse, por tanto,
también tendríamos un valor nulo en el atributo foto.

eid enombre calificacion foto


123 Obiang Belobe 7,7
234 Bindang Bakale 6,5 NULL
345 Bilogo Mba NULL

Observación: Los valores nulos son interesantes, pero debemos tener bastante cuidado a la hora de
formular consultas a una base de datos donde pueden existir valores nulos. Tendremos que manejar
esas situaciones de forma especial. Más adelante estudiaremos los efectos que puede tener la
presencia de estos valores, por ahora vemos un ejemplo:

Consulta (query): Nombres de alumnos con calificación >5

Evidentemente, esperamos entre nuestros resultados a Obiang Belobe y Bindang Bakale, pero ¿qué
hay de Bilogo Mba?, ¿debería aparecer en los resultados?, pues claro que no, ya que al no estar
disponible su nota, no tenemos garantía alguna de que su nota sea mayor que 5.

Otro ejemplo:

Consulta (query): Nombres de alumnos con calificación <7

Pues entre los resultados, es seguro que aparecerá Bindang Bakale, pero ¿que hay de Bilogo Mba?,
como en el caso anterior, no hay ninguna garantía acerca del valor de su nota, por tanto tampoco
aparecerá. Bueno, hasta ahora todo parece razonable, pero veamos que pasa en este último caso:

Consulta (query): Nombres de alumnos que tengan una calificación >7 OR <=7.

Pues aparentemente, esta consulta debería mostrarnos el total de alumnos que hay en la tabla, pues la
nota de cualquier alumno estará ente 0 y 10 puntos, sea cual sea cumplirá una de las dos condiciones;
pero resulta que este comportamiento no se cumple cuando existen valores nulos entre los datos, y
esta es la razón por la que habrá que andarse con cuidado cuando tratemos con sistemas que admiten
valores nulos.

 Clave (Key): Es uno de los conceptos más importantes en el modelo relacional, la clave es un
atributo cuyo valor es único para cada fila de la tabla. Nunca puede repetirse el valor entre dos
o más datos de un atributo definido como clave.
En las tablas de nuestro ejemplo, intuitivamente podemos determinar que el atributo
9

identidad del estudiante (eid) será una clave, ya que sabemos de sobra que el documento de
Página

identidad no es compartido en ninguna parte del mundo. Por otra parte la situación para la
tabla universidad, no es tan clara. Por ejemplo el nombre de la universidad podría ser una
clave, pero corremos el riesgo de que existan dos o más universidades en el mundo real que
tengan el mismo nombre (podría existir otras universidades llamadas UNGE en otras
provincias). Esto da lugar al concepto de clave múltiple.
 Clave múltiple: es una clave definida mediante un conjunto de atributos, es decir, no se puede
repetir en ninguna fila, una misma combinación de valores de los atributos que conforman la
clave.

En el caso de la tabla universidad, podemos definir como clave, la combinación de nombre de la


universidad y provincia. Es poco probable que dentro de la misma provincia o localidad, aparezcan dos
universidades con el mismo nombre.

Observación: Cuando diseñamos la base de datos sobre papel, escribiendo los nombres de tablas y sus
atributos, es habitual indicar los atributos clave mediante subrayado de sus nombres.

Importancia de las claves: Las claves tienen mucha utilidad en el modelo relacional, por ejemplo, se
utilizan para:

o Localizar tuplas concretas: Si conocemos la identidad de un estudiante y queremos


conocer información sobre dicho estudiante, podemos lanzar una consulta usando
como condición el número de identidad que conocemos.
o Los sistemas de bases de datos utilizan las claves para crear estructuras indizadas
especiales, o almacenan los datos de una forma especial que permite hacer búsquedas
rápidas basándose en las claves de las tablas.
o Para referenciar a una tabla desde otra, no existe el concepto de puntero en sistemas
de bases de datos, por lo tanto, la forma de hacer tal referencia es mediante la clave
única de la tabla que queremos referenciar.

Para concluir, quiero mostrarles cómo se crea una relación (tabla) en el lenguaje de consulta de alto
nivel SQL:

o create table estudiante(eID, enombre, calificacion, foto)

Si queremos especificar el dominio o tipo de los atributos sería:

o create table universidad(unombre string char(2) provincia, matricula integer)

3. CONSULTANDO (QUERYING) BASES DE DATOS RELACIONALES

Aprendamos un poco sobre cómo lanzar consultas (queries) a bases de datos


relacionales. Utilizaremos un enfoque genérico, es decir, no vamos a utilizar ningún
lenguaje de consulta; más adelante ya trabajaremos con lenguajes concretos.
Es habitual en el mundo de las bases de datos, representarlas mediante un disco
gigante como veremos a continuación.
10
Página
Ya conocemos los pasos básicos para crear y utilizar una base de datos relacional:
a) Diseñar el esquema o estructura y crearlo mediante un LDD

El esquema consiste en la estructura de las relaciones y los atributos de dichas


relaciones, junto con los respectivos tipos de datos de cada atributo.
b) Realizar la carga masiva de los datos iniciales

Es bastante frecuente que la carga inicial de datos provenga de una fuente externa,
como unos archivos Excel, archivos csv, etc. La figura siguiente muestra un proceso
de carga de datos desde un fichero externo; una vez cargados los datos, ya
tendremos cierta cantidad de tuplas o filas en las tablas de la base de datos,
entonces podemos proceder al paso siguiente.

c) Repetir: Ejecutar consultas y modificaciones

Este tercer paso se repetirá continuamente durante el ciclo de explotación de la base


de datos. Normalmente las consultas se hacen desde aplicaciones o sitios web, pero
en nuestros ejemplos gráficos vamos a suponer que usuarios humanos están
consultando directamente la base de datos, la siguiente ilustración muestra
gráficamente lo que ocurre constantemente durante la explotación de una base de
datos.
Un usuario lanza la consulta
Q y obtiene la respuesta A,
Otro usuario lanza Q2 y
recibe A2

El mismo usuario anterior u otro


usuario lanza una modificación M,
Y recibe confirmación “realizado”
de la base de datos

Las bases de datos relacionales soportan consultas ad-hoc en lenguajes de alto nivel:
con el término ad-hoc, nos referimos a que es posible plantear consultas que no han
sido premeditadas, podemos formular consultas que se nos ocurran de repente. No
hay necesidad de escribir todo un programa para una consulta específica, podemos
utilizar el lenguaje para formular la consulta mientras pensamos en lo que queremos
preguntar a la base de datos.
Y como ya se ha dicho antes, los lenguajes soportados por los sistemas relacionales,
son de alto nivel, lo que significa, posibilidad de escribir de forma compacta
consultas complicadas y sin preocuparnos de formular el algoritmo necesario para
extraer los resultados de la base de datos.
Veamos algunos ejemplos de consultas que podemos plantear en una base de datos,
11

usando la base de datos imaginaria sobre admisiones de estudiantes a


universidades:
Página
Queremos lista de todos los estudiantes con calificación mayor que 7 que han
solicitado únicamente en la UNGE y en SIPACO.
Queremos todos los departamentos de INFORMÁTICA de BN que tengan menos de
500 solicitantes
Universidad con la mayor tasa de aceptación de estudiantes durante los últimos 5
años.
Bien, las consultas propuestas pueden parecer intimidantes, o muy complejas, pero
en realidad todas se pueden formular en pocas líneas en alguno de los lenguajes de
consulta. En realidad, encontraremos diversas situaciones respecto a las consultas:
Consultas fáciles de formular; otras más difíciles
Consultas que resultan fácil para el SGBD, es decir, fácilmente consigue ejecutarlas
con máxima eficiencia; otras que le costarán más al SGBD; No existe correlación
entre la facilidad de formular y la facilidad de ejecutar eficientemente.

Observación terminológica: A menudo los profesionales hablan de “Lenguaje de


consulta”, de un SGBD; Debemos tener en cuenta que se usa como sinónimo del
LMD (Lenguaje de manipulación de datos o DML, en inglés). Y al hablar de LMD,
hablamos tanto de consultar como de modificar los datos de la BD.
Observación: Las consultas devuelven relaciones o tablas (“composición”, “cierre”)
Al formular una consulta sobre dos o tres tablas, lo que obtenemos generalmente es
una tabla como resultado.
CIERRE: El fenómeno de obtener como resultado el mismo tipo de objeto que has
consultado, se conoce como cierre de un lenguaje, y es una característica
interesante, ya que nos permite lanzar nuevas consultas sobre resultados de
consultas anteriores o combinar la relación resultante con otras relaciones existentes
en la BD, esto es lo que se conoce como composicionalidad.
COMPOSICIONALIDAD: La habilidad de poder ejecutar una consulta sobre el
resultado de una consulta previa.

12
Página
4. LENGUAJES DE CONSULTA (QUERY)

 Algebra Relacional

Es un lenguaje formal, por su nombre deducimos que es un algebra, por lo que está
bastante bien fundamentado teóricamente.
 SQL

Es un lenguaje real, un lenguaje implementado. Es el tipo de lenguaje que se utiliza


en la explotación de SGBD reales. El lenguaje SQL tiene sus fundamentos basados
en el Algebra relacional, es decir, la semántica de este lenguaje proviene de las reglas
del algebra relacional.
Para terminar, veamos un ejemplo de consulta en cada uno de estos lenguajes:
Consulta: número de identidad de estudiantes con calificación mayor que 7 que
solicitan en la UNGE.
- Usando AR:
( ∧ (
⋈ )
-

Select estudiante.eID
From estudiante, solicitud
Where estudiante.eID = solicitud.eID
And calificacion > 7.0 and uNombre =
‘UNGE’
Y vemos la diferencia de operadores y palabras clave de ambos lenguajes, pero las
dos expresiones expresan (valga la redundancia) exactamente lo mismo, por tanto,
son totalmente equivalentes.
En el tema siguiente estudiaremos las bases fundacionales del lenguaje SQL a través
del algebra relacional. Una vez comprendido estas bases, procederemos al estudio del
lenguaje SQL.

13
Página
CURSO DE INTRODUCCIÓN A BASES DE DATOS
Profesor: LUIS ICHAICOTO BONCANCA

Rev.: 01, 25-Enero-2021

TEMA 2: ALGEBRA RELACIONAL

PORTADA
Introducción
Es un lenguaje formal, es el álgebra que describe los fundamentos sobre los que se
crean los lenguajes implementados como el SQL.

Veamos los fundamentos básicos de este lenguaje de consultas.

RECORDAD: Una consulta (expresión) sobre un conjunto de relaciones produce


como resultado una relación. Lo interesante es que sobre este resultado, podemos
lanzar consultas y/o combinar este resultado con las relaciones ya existentes.

Utilizaremos como base de datos para los ejemplos, la que llamaremos


ADMISIONES, y tiene la siguiente estructura o esquema:

Universidad (uNombre, provincia, matricula)


universidad
uNombre Provincia matricula

Estudiante (eID, eNombre, Calificacion, cInstituto)

estudiante
eID eNombre calificacion cInstituto

Solicitud (eID, uNombre, Especialidad, decision)


solicitud
eID uNombre especialidad decision

Los atributos subrayados son las respectivas claves de dichas relaciones, es decir,
Los nombres de Universidad (uNombre) son únicos, la identidad de cada estudiante
(eID) es única y la solicitud de una especialidad en una universidad concreta solo
puede hacerse una vez por cada estudiante (Ej. un estudiante solo puede tener una
única solicitud de la especialidad de mecánica en la UNGE)
15
Página
1. CONSULTA MAS ELEMENTAL

En algebra relacional, la consulta más simple que se puede formular es el nombre


de una relación. Esta consulta da como resultado una copia de la relación, es decir,
muestra todos los registros o tuplas que hay en la relación correspondiente.

2. OPERADORES

Con los operadores, vamos a filtrar, dividir y combinar relaciones.

Filtrar: Dada una relación de n registros, con la aplicación del operador


correspondiente, obtendremos una relación resultante con m (número de registros
que cumplen la condición del filtro) registros, siendo m <= n.

Dividir: Dada una relación de n atributos, con la aplicación del operador


correspondiente, podemos producir un resultado con m atributos, siendo m < n.

Combinar: Dadas dos relaciones de n y m atributos respectivamente, que pueden


tener algún atributo común a ambos, podemos producir relaciones que contengan
atributos de ambas relaciones, combinados bajo criterios lógicos.

2.1. OPERADOR DE SELECCIÓN s


Este operador se utiliza cuando queremos obtener un subconjunto de tuplas o filas
que cumplen una determinada condición o serie de condiciones.

SINTAXIS: ( )

Condición(es): se refiere a una o varias condiciones que deben cumplir uno a


varios atributos resultantes de la expresión.

EXPRESION: Puede ser una tabla o consulta de algebra relacional, que como
sabemos, dará como resultado una relación.
Ejemplos:

a) Mostrar los estudiantes con calificación mayor que 7


( )
La expresión anterior devuelve un subconjunto de la tabla estudiante, donde
solo aparecen las filas que cumplen la condición de tener un valor mayor que
7 en el atributo calificación.

b) Mostrar estudiantes con calificación mayor que 7 y cInstituto <200

∧ ( )
Si además queremos que solo aparezcan aquellos estudiantes que han asistido
en institutos con capacidad inferior a 200 alumnos, tenemos que anidar las
16

condiciones utilizando el operador Y-lógico ( ó 1⋀ ó 2)


Página
c) Mostrar solicitudes de la especialidad INFORMATICA en la UNGE

⋀ ( )

Observaciones:

 Cuando la condición afecta a un atributo tipo texto, el valor del atributo se


pone entre comillas simples. Mientras que para valores numéricos, no hacen
falta las comillas.
 Para concatenar varias condiciones, utilizamos el operador Y-lógico para
separar las distintas condiciones, Y-lógico nos dice que exigimos que los
resultados cumplan la cadena de condiciones impuestas.

2.2. OPERADOR DE PROYECCION

Este operador se utiliza para obtener determinados atributos o columnas de una


relación.

SINTAXIS: ( )

Atributos: Se refiere a una lista de nombres de atributos que queremos obtener,


separados por comas (,)

EXPRESION: Puede ser una tabla o consulta de algebra relacional, que como
sabemos, dará como resultado una relación.
Ejemplos:

a) Mostrar las identificaciones (ID) de los estudiantes y las decisiones de todas la


solicitudes.
, ( )
La expresión anterior devuelve una relación con dos atributos y con el mismo
número de tuplas o registros que hay en la tabla solicitudes.

2.3 COMBINACION DE LOS OPERADORES SELECCIÓN Y PROYECCION

Cuando queremos seleccionar tuplas que cumplan una o varias condiciones y


además estemos interesados solo en unos cuantos atributos de estas tuplas,
debemos anidar las expresiones de algebra relacional en el orden correcto.

Ejemplo:

Queremos conocer sólo la identidad y el nombre de los estudiantes con calificación


mayor que 7:
17

Para ello, debemos aplicar primero el operador selección para quedarnos con una
relación que contenga solo los estudiantes que cumplan la condición (calificación
Página

>7).
( )
Una vez tenemos la expresión que nos devuelve ese subconjunto de la tabla
estudiantes, le aplicamos la proyección indicando solo los dos atributos eID y
eNombre.

, ( ( ))

Observaciones:

 Como se puede ver, de los ejemplos se desprende que podemos lanzar


consultas que operan sobre expresiones. Esto es posible porque el orden de
ejecución de las expresiones es desde las más internas hasta las más
externas.
a) Es recomendable utilizar los paréntesis para indicar los límites de actuación
de los operadores, así como para indicar las operaciones que deben realizarse
primero – siempre se ejecutan las expresiones que hay dentro de los
paréntesis, luego se hace una ejecución de derecha a izquierda (reglas de
precedencia).

2.4 VALORES DUPLICADOS

Formulemos la siguiente consulta: Queremos una lista de especialidades solicitadas


y las decisiones sobre dichas solicitudes.

Para ello hacemos la siguiente proyección sobre la relación de solicitudes:

, ( )

Pues, intuitivamente pensamos en que el resultado de esta consulta nos presentará


múltiples valores duplicados, ya que es muy probable que varios estudiantes
soliciten una especialidad, es decir, si hay cinco estudiantes que han solicitado
INFORMATICA y han sido aceptados, es lógico pensar que aparecerán cinco tuplas
con los valores (INFORMATICA, SI).

Lo que queremos aclarar en este apartado, es que la semántica del algebra


relacional, establece como norma -la eliminación de valores duplicados-. Es decir,
ante un resultado que lógicamente tiene varios valores duplicados, en los resultados
de algebra relacional se eliminan los duplicados y se presenta una copia única para
cada tupla con duplicados.

La razón de esta regla semántica es que el álgebra relacional, matemáticamente está


basado en la teoría de conjuntos.

A diferencia del lenguaje SQL que está basado en multi-conjuntos o bolsas, donde sí
se conservan los duplicados debido a que la multiplicidad de los elementos de un
multi-conjunto siempre es ≥1, mientras que para los conjuntos la multiplicidad es
estrictamente =1.
18
Página
2.5 OPERADOR PRODUCTO CARTESIANO

El operador producto cartesiano también conocido como producto cruz, es el primer


operador que veremos que actúa sobre dos relaciones o expresiones.

SINTAXIS: ×

Este operador combina dos relaciones de la siguiente forma:

a) En cuanto al esquema o estructura de la relación resultante, es como si


cogiera el esquema de la primera relación y lo uniera (pegar a la derecha)
físicamente al esquema de la segunda relación, dando lugar a un esquema
cuyos atributos son la suma de atributos de ambas relaciones.

estudiante solicitud
eID eNombre calificacion cInstituto eID uNombre especialidad decision
123 Antonio 9 300 123 UNGE MECANICA SI
456 Etundi 8,5 200 456 AUCCA ELECTRONICA NO

Relación resultante de nombre no determinado


eID eNombre calificacion cInstituto eID uNombre especialidad decision
123 Antonio 9 300 123 UNGE MECANICA SI
123 Antonio 9 300 456 AUCCA ELECTRONICA NO
456 Etundi 8,5 200 123 UNGE MECANICA SI
456 Etundi 8,5 200 456 AUCCA ELECTRONICA NO

b) En cuanto a los datos o tuplas, tendremos todas las combinaciones posibles


entre las tuplas de ambas relaciones, es decir, para cada tupla de la primera
relación, se junta con cada tupla de la segunda relación, de forma tal que la
relación resultante tendrá M x N tuplas, siendo M el número de tuplas de la
primera relación y N el número de tuplas de la segunda relación.

Observación: Al combinar dos relaciones en una, en general puede darse el caso de


que tengamos atributos con el mismo nombre en ambas relaciones. Para distinguir
estos atributos matemáticamente, usaremos la siguiente notación:
Nombre_de_relación.Nombre_de_atributo, por ejemplo, estudiante.eID,
solicitud.eID.

En principio el producto cartesiano parece carecer de interés, pero su interés se


manifiesta cuando se utiliza en combinación con otros operadores. Por ejemplo:

Queremos conocer los nombres y las calificaciones de los estudiantes que


asistieron a institutos de más de 200 alumnos, que solicitaron la especialidad
de INFORMATICA y fueron RECHAZADOS (decision = NO).

La formulación de esta consulta nos exige acceder a los registros de las relaciones
estudiante y solicitud, ya que la información que necesitamos se encuentra
dispersada entre ambas relaciones.

Para ello, primero utilizaremos el producto cartesiano para centralizar toda la


19

información en una sola relación “gigante”.


Página

( × )
La expresión anterior nos devuelve una relación que contiene ocho atributos (cuatro
de estudiante y cuatro de solicitud).

A continuación vamos a lanzar una consulta de selección sobre la expresión anterior,


esta selección debemos hacerla imponiendo la condición de igualdad entre los
atributos eID de la tabla estudiantes y los eID de la tabla solicitudes; así
sabemos que tenemos las solicitudes reales de cada alumno (son las únicas tuplas
con sentido entre los resultados del producto cartesiano).

. . ( × )
Seguidamente, añadimos las condiciones adicionales que nos exige la consulta:

. . ⋀ ⋀ ⋀ (
× )

Y finalmente, nos quedamos solo con los atributos que nos exige la consulta,
poniendo toda la expresión anterior en un paréntesis, y aplicando PROYECCION a
dicha expresión:

, ( . . ⋀ ⋀ ⋀

( × ))

2.6. OPERADOR UNION NATURAL ⋈


SINTAXIS: ⋈

Es un operador del algebra relacional que simplifica el uso del producto cartesiano
en el caso particular de los atributos con igual nombre en ambas relaciones, es decir,
la unión natural realiza un producto cartesiano aplicando internamente la condición
de igualdad para todos los atributos con igual nombre en ambas relaciones.

Observaciones:

 Es necesario analizar si los atributos con el mismo nombre, significan lo


mismo. Solo en caso afirmativo, tendrá sentido la unión natural. En el ejemplo
anterior se cumple ya que el estudiante.eID se refiere a la identidad de un
alumno así como solicitud.eID, se refiere a la identidad del alumno que hace
una solicitud.
 Otra cosa que hace la unión natural, es eliminar el atributo duplicado en la
relación resultante, ya que al tratarse de los mismos valores, deja de tener
sentido conservar dos columnas con los mismos valores.

Ejemplo 1: Queremos conocer los nombres y las calificaciones de los


estudiantes que asistieron a institutos de más de 200 alumnos, que
solicitaron la especialidad de INFORMATICA y fueron RECHAZADOS (decision =
NO).
20

Primero, utilizando la unión natural, vemos que no tenemos que añadir la condición
Página

de igualdad entre los atributos con el mismo nombre entre ambas relaciones, ya que
de esto se encarga el propio operador⋈: ( ⋈ )
A continuación podemos añadir el resto de condiciones que nos exige la consulta:

∧ ∧
( ⋈ )
Y finalmente podemos proyectar para quedarnos con los atributos que nos interesan
(eNombre y calificacion).

, ( ∧ ∧
( ⋈ ))
Ejemplo 2: Queremos los nombres y las calificaciones de estudiantes que asistieron a
institutos con capacidad para más de 200 alumnos, que hayan solicitado
INFORMATICA en universidades cuya matrícula cuesta más de 50000 y que han sido
rechazados.

En primer lugar, nos damos cuenta que ahora el problema involucra una tercera
relación (universidad). Para formular esta consulta, tenemos que hacer una unión
natural también con la tabla de universidad y añadir una condición más a la lista de
condiciones anteriores. – En el ejemplo solo se han resaltado las modificaciones
hechas al ejemplo anterior.

, ( ∧ ∧ ∧
( ⋈( ⋈ )
Observaciones:
 Técnicamente la unión natural es una operación binaria, es decir, actúa sobre
dos relaciones. Así que con los paréntesis debemos determinar el orden en que
queremos que se hagan las uniones, teniendo en cuenta los atributos que
deben igualarse: se debe unir universidad con solicitud por el atributo común
uNombre y luego este resultado se debe unir a estudiantes por el campo eID.

 La unión natural no supone una aportación potente entre las herramientas


del algebra relacional, ya que se puede implementar sus efectos utilizando el
producto cartesiano, la unión natural de puede reescribir de esta forma:

⋈ = ( )∪ ( )( . . ∧ . . …( × )

Es decir, la unión natural equivale hacer un producto cartesiano sobre dos


expresiones, y sobre dicho resultado lanzar una SELECCIÓN donde las condiciones
serán igualar los atributos equivalentes de ambas relaciones y sobre dicho resultado
proyectar para quedarnos con los atributos relevantes (cogiendo una sola vez los
atributos repetidos).

2.7. OPERADOR UNION THETA ⋈


Este operador, al igual que el operador unión natural, no supone una herramienta
21

imprescindible (no añade potencia al lenguaje, ya que se puede reescribir utilizando


operadores básicos) en el álgebra relacional, pero si conveniente al igual que la unión
Página

natural.
SINTAXIS: ⋈
El subíndice theta representa una condición tal como vimos para el operador de
selección s. básicamente la UNION THETA equivale a aplicar una consulta de
selección sobre el producto cartesiano de dos expresiones aplicando la condición
THETA.

⋈ ≡ ( × )

Visto así, parece irrelevante su mención en este texto. Pero la razón de mencionarlo
es que varios sistemas de gestión de bases de datos (SGBD) implementan esta
operación como la operación básica para combinar relaciones, es decir el término
“unión” o “join”, en muchos casos significa unión theta.

En resumen, lo que hace es: Coge dos relaciones, combina las dos relaciones y
devuelve una relación que contiene solo las tuplas que cumplen la THETA-
CONDICION.

2.8. RESUMEN:

 El álgebra relacional es un lenguaje formal, que opera sobre conjuntos de


relaciones y los resultados que produce son también relaciones
 La consulta más elemental posible en este lenguaje es: el nombre de una
relación
 Utiliza operadores para filtrar, dividir y combinar relaciones
 Hasta ahora hemos estudiado los siguientes operadores:
o SELECCIÓN (SELECT): para seleccionar filas de una relación
o PROYECCIÓN (PROJECT): para seleccionar columnas de una relación
o Producto cartesiano o cruz: para combinar dos relaciones, haciendo
cada posible combinación de las tuplas de ambas relaciones
o UNIÓN NATURAL (natural join): Que no es un operador primitivo, pero
si una herramienta muy útil para combinar dos relaciones imponiendo
automáticamente la condición de igualdad sobre los atributos
equivalentes de ambas relaciones.
o UNIÓN THETA (theta join): Otra herramienta útil para combinar y
forzar el cumplimiento de una condición genérica.
22
Página
2.9. OPERADORES DE CONJUNTOS

A continuación vamos a estudiar algunos operadores que operan sobre conjuntos de


relaciones tales como el UNION, DIFERENCIA e INTERSECCIÓN; también veremos el
operador RENOMBRAR así como diferentes notaciones para expresiones de algebra
relacional.

RECORDAD: Al aplicar una consulta o expresión de algebra relacional a un conjunto


de relaciones, obtenemos como resultado o respuesta otra relación.

Seguiremos trabajando con la base de datos de ejemplo admisiones (admisiones de


estudiantes a universidades) cuyo esquema ya conocemos y podemos consultar
siempre en cada pie de página de este documento.

2.9.1 OPERADOR UNION

SINTAXIS: ∪
Requisito: Las reglas del algebra relacional exigen que EXP 1 y EXP 2 tengan un
esquema o estructura idéntico para poder hacer la UNION.

En la teoría de conjuntos, la unión de dos (o más) conjuntos es una operación que


resulta en otro conjunto, cuyos elementos son los mismos de los conjuntos iniciales. Por
ejemplo,

Sea el conjunto A= [a, b, c] y el conjunto B= [1, 2,3]; ∪ = [ , , , 1,2,3]

Supongamos que queremos una lista de nombres de universidades y nombres de


estudiantes. Como sabemos, los nombres de universidades están en la relación
universidad bajo el atributo uNombre y los nombres de estudiantes están en la
relación estudiante, bajo el atributo eNombre.

universidad
uNombre Provincia matricula N/D
UNGE BN 50000 UNGE
AUCCA LT 200000 AUCCA
UNED BS 150000 UNED
IYANGA
estudiante BONEKE
eID eNombre calificacion cInstituto BAKALE
123 IYANGA 7,5 200
456 BONEKE 8,3 150
234 BAKALE 6,5 300

Intuitivamente podemos pensar que es posible generar esta lista con los operadores
ya estudiados hasta ahora para combinar diferentes relaciones como (PRODUCTO
CARTESIANO O UNION NATURAL).

El problema que presentan operadores como el producto cartesiano o la unión


natural es que combinan los datos de forma horizontal, es decir, por filas o tuplas
con todos sus atributos, eso no es lo que pedimos en este supuesto, más bien
23

queremos combinar datos verticalmente.


Página
Podemos intentar haciendo una proyección del atributo uNombre por un lado y
proyección del atributo eNombre por otro, y finalmente hacer un producto cartesiano
de ambos resultados, pero nos quedaría el siguiente resultado, que nos manifiesta la
horizontalidad de estos operadores; lo cual no resuelve nuestro problema.

( )× ( )

universidad
N/D N/D
uNombre Provincia matricula
UNGE BN 50000 UNGE IYANGA
AUCCA LT 200000 UNGE BONEKE
UNED BS 150000 UNGE BAKALE
AUCCA IYANGA
estudiante AUCCA BONEKE
eID eNombre calificacion cInstituto AUCCA BAKALE
123 IYANGA 7,5 200 UNED IYANGA
456 BONEKE 8,3 150 UNED BONEKE
234 BAKALE 6,5 300
UNED BAKALE

Para resolver el problema, en lugar del operador producto cartesiano, utilizaremos el


operador UNION, este operador si permite una combinación vertical de los datos.

( )∪ ( )

La expresión anterior aunque sintácticamente correcta, dará como resultado un


error, ya que no se está cumpliendo el requisito para la UNION en este caso, más
adelante veremos cómo corregimos este problema.

2.9.2 OPERADOR DIFERENCIA

SINTAXIS: −
Requisito: Las reglas del algebra relacional exigen que EXP 1 y EXP 2 tengan un
esquema o estructura idéntico para poder hacer la DIFERENCIA.

Ejemplo 1: Queremos la identidad (eID) de estudiantes que no han hecho ninguna


solicitud.

Formular esta consulta puede parecer complicado, pero resulta bastante fácil como
veremos.

Si proyectamos sobre la tabla estudiantes cogiendo solo el atributo eID, ya


tendremos el conjunto de todas las identidades de los estudiantes, y lo llamaremos
conjunto A.

A continuación, proyectando sobre la tabla solicitudes, cogiendo también el atributo


eID de esta tabla, tendremos ahora el conjunto de identidades que sí han hecho
alguna solicitud, este será nuestro conjunto B.

Ahora bien, podemos observar que el conjunto B, es un subconjunto del conjunto A.


24

Y que basta con eliminar del conjunto A, todos aquellos elementos que existen en el
conjunto B.
Página
estudiante
solicitud
eID eNombre calificacion cInstituto
eID uNombre especialidad decision
123 IYANGA 7,5 200
123 UNGE INFORMATICA SI 456 BONEKE 8,3 150
456 AUCCA ELECTRONICA NO 234 BAKALE 6,5 300
234 AUCCA INFORMATICA SI 235 OBIANG 7 200
124 ANGESOMO 9 250

La consulta formulada en algebra relacional sería:

( )− ( )

Veámoslo de forma gráfica y con los elementos clásicos de la teoría elemental de


conjuntos (diagramas de venn).
A
B
123

456
123
234
456
235
234
124

Diferencia de A y B (A – B)

235

124

Ejemplo 2: Queremos las identidades (eID) y los nombres de estudiantes que no han
hecho ninguna solicitud.

Esta consulta es un poco más compleja que la anterior, uno podría pensar que basta
con añadir a la proyección sobre la tabla estudiante, el atributo eNombre. Pero, si lo
pensamos un poco más, esto violaría el requisito del operador UNION que dice: Los
esquemas de ambas expresiones deben ser idénticos. Esquema 1(eID, eNombre)
es diferente de Esquema 2 (eID).

Una forma de formular esta consulta sería, partiendo del resultado de la consulta
anterior:
( )− ( )
25

Hacemos una UNION NATURAL con la tabla estudiante (donde tenemos el atributo
Página

eNombre). ( ( )− ( )) ⋈
Con esta consulta obtenemos un esquema idéntico al de la tabla estudiante, pero
estamos seguros que solo aparecen las tuplas de los alumnos que nunca han
solicitado, de modo que ahora podemos hacer una proyección sobre este resultado,
quedándonos con los atributos que nos interesan.

, (( ( )− ( )) ⋈ ))

2.9.3 OPERADOR INTERSECCION

SINTAXIS: ∩
Requisito: Las reglas del algebra relacional exigen que EXP 1 y EXP 2 tengan un
esquema o estructura idéntico para poder hacer la INTERSECCION.

En teoría de conjuntos, la intersección de dos (o más) conjuntos es una operación


que resulta en otro conjunto que contiene los elementos comunes a los conjuntos de
partida. Por ejemplo, dado el conjunto de los números pares P y el conjunto de los
cuadrados C de números naturales, su intersección es el conjunto de los cuadrados
pares.

En otras palabras: Cómo, por ejemplo, si A = {a, b, c, d, e, f} y B = {a, e, i, o, u},


entonces la intersección de dichos conjuntos estará formada por todos los elementos
que estén a la vez en los dos conjuntos, esto es: A∩B = {a, e}

Ejemplo 1: Queremos saber si hay nombres de alumnos que coinciden con nombres
de universidades

estudiante universidad
eID eNombre calificacion cInstituto uNombre Provincia matricula
123 IYANGA 7,5 200 UNGE BN 50000
456 BONEKE 8,3 150
234 BAKALE 6,5 300
AUCCA LT 200000
235 OBIANG 7 200 UNED BS 150000
127 MPA SIPACO 9 250 MPA SIPACO AN 40000

Para formular esta consulta, basta con hacer dos proyecciones y aplicar la
intersección a ambas expresiones.

( )∩ ( )

Observación: La operación de intersección, no supone una mejora imprescindible


entre los operadores del algebra relacional. Ya que se puede conseguir sus resultados
utilizando operadores primitivos como vamos a demostrar, concretamente mediante
el operador DIFERENCIA:
Haciendo la diferencia de área rosa – área verde, nos queda
∩ ≡ −( − ) justamente la intersección.

En verde tenemos los elementos E1


– E2, es decir, elementos que solo E2
E1
aparecen en E1 y no en E2.
26

En rosa tenemos todos los


Página

elementos de E1.
E1: Contiene elementos que también están en E2 y otros que no lo están

E1 – E2: Contiene elementos que pertenecen únicamente al conjunto E1

Entonces está claro que podemos obtener la intersección eliminando de E1, los
elementos únicos de E1, dejando así los que éste conjunto tiene en común con el
conjunto E2.

Por tanto: ∩ ≡ −( − )

También podemos demostrarlo de otra forma, atendiendo al requisito de estos


operadores (que las relaciones implicadas tengan el mismo esquema).

Por tanto, si se cumple el requisito, podemos afirmar y probar que:

∩ ≡ ⋈

Para entenderlo, solo debemos recordar la definición de UNION natural, es decir,


saber qué hace la unión natural.

2.9.4 OPERADOR RENOMBRAR

SINTAXIS GENERAL: _ ( _ _ , _ _ … )( )

Para cambiar solo el nombre de la relación: _ ( )

Para cambiar solo los nombres de atributos:


, ,… _ _ ( )

Se trata de un operador que resulta necesario muchas veces para poder expresar
determinadas consultas o queries.

Este operador reasigna o sustituye el esquema (nombre de relación y nombres de


sus atributos) del resultado de la expresión sobre la que se aplica.

Ejemplo1: Queremos una lista con los nombres de universidades y nombres de


estudiantes.

Esta es la solución que dimos al estudiar el operador UNION, pero dijimos


claramente, que dará como resultado, ERROR; porque los esquemas de ambas
proyecciones no son idénticas.

( )∪ ( )

Para resolver este problema, debemos renombrar una de las dos expresiones como
sigue:

)( ( )) ∪ )( ( ))
27

( (
Página

Como vemos ahora tendremos dos relaciones con nombre lista y cuyo único atributo
se llamará nombres.
Observación: Una de las aplicaciones principales de este operador es reasignar
esquemas para cumplir el requisito que exigen los operadores de conjuntos (UNION,
DIFERENCIA, INTERSECCION).

Otra aplicación importante del operador RENOMBRAR, es para eliminar los casos de
ambigüedad en las AUTO-UNIONES (unión de una relación consigo misma).

Ejemplo: Queremos una lista con dos columnas de manera que nos muestre pares
de universidades que pertenecen a la misma provincia.

Un ejemplo de resultado: UNGE MPA SIPACO


AUCCA POLITECNICO

Se entiende aquí que UNGE y MPA SIPACO están en la misma provincia así como
AUCCA y POLITECNICO, están una misma provincia diferente a la que pertenecen
UNGE y MPA SIPACO.

Un primer intento para formular esta consulta sería

( × )

La consulta anterior resultará en un ERROR, debido a la ambigüedad por tener dos


instancias de una misma relación, ¿cómo distinguimos una instancia de la otra? Al
decir provincia=provincia, ¿a qué instancia nos referimos?

Para resolver el problema, utilizaremos el operador RENOMBRAR para distinguir las


dos instancias, de esta forma:

( ( , , ( )
× ( , , ( ))

Otra solución más sencilla con la UNION natural sería:

( , , ( )
⋈ ( , , ( )

Observad que hemos igualado el nombre del atributo provincia, esto es un requisito
para que pueda funcionar el operador UNION NATURAL. Este operador solo
conserva las tuplas que tienen el mismo valor en aquellos atributos comunes a las
dos relaciones implicadas.

Observación: El resultado de esta consulta, nos producirá algunas tuplas en las que
tendremos las dos columnas del resultado con el mismo valor es decir, y tendremos
dos instancias de esta situación, aparecerán resultados como:
Problema 2: Tenemos el
UNGE MPA SIPACO
MPA SIPACO UNGE resultado buscado,
UNGE UNGE prácticamente duplicado.
Problema 1: Resultado AUCCA POLITECNICO
innecesario. No nos da POLITECNICO AUCCA
28

AUCCA AUCCA
información útil.
MPA SIPACO MPA SIPACO
Página

POLITECNICO POLITECNICO
¿Qué puedes hacer para eliminar estas tuplas innecesarias?— ¡PIENSA!
2.10 OTRAS NOTACIONES APLICABLES

2.10.1 Uso de sentencias de asignación

Las sentencias de asignación son una forma de presentar expresiones de algebra


relacional, descomponiéndolas en sus distintas partes.

Las expresiones vistas anteriormente, pueden ser reescritas con el propósito de


modularizar o compactar la expresión, aquí solo queremos hacerle ver que existe esta
alternativa y es preferida por algunos usuarios del algebra relacional.

Así, la expresión del ejemplo anterior sobre pares de universidades de la misma


provincia, puede reescribirse mediante asignaciones de la siguiente forma:

Asignamos a la variable uni1, una instancia de la tabla universidad con los


atributos renombrados.

≔ , , ( )
Del mismo modo, procedemos para la segunda instancia de la tabla universidad
(uni2).

≔ , , ( )
Finalmente asignaremos a la variable pu (pares de universidades), la UNION
NATURAL DE las dos anteriores:

≔ ⋈
Y ahora podemos asignar a la variable RES (respuesta), el resultado final de la
consulta:

≔ ( )
Podemos observar como de esta forma, la expresión se compacta bastante.

2.10.2 ARBOLES DE EXPRESIONES

Otra forma de escribir expresiones de algebra relacional es mediante arboles de


expresiones, son comúnmente utilizadas y permiten una visualización más detallada
de la estructura de las expresiones.

También es el caso que durante la compilación del lenguaje SQL en sistemas de


bases de datos, a menudo se compila resultando en un árbol de expresión parecido
al que vamos a construir en el siguiente ejemplo:

Ejemplo: Queremos las calificaciones de estudiantes que han solicitado


INFORMATICA en la provincia de Bioko Sur.
29

Vemos que la formulación de esta consulta implica las tres tablas de nuestra base de
Página

datos
Nuestro árbol tendrá como hojas, las tres relaciones de nuestra base de datos
(universidad, estudiante y solicitud). En algebra relacional, las hojas siempre serán
nombres de relaciones.

1. Sobre estas tres hojas, aplicaremos una UNION NATURAL, que como sabemos,
impone automáticamente una condición de igualdad sobre los atributos
idénticos en nombre y tipo de datos de todas las relaciones implicadas.
2. Sobre la UNION NATURAL, aplicaremos una SELECCIÓN con las dos
condiciones del problema provincia= ‘Bioko Sur’ y especialidad =
‘INFORMATICA’
3. Finalmente, sobre la SELECCIÓN, aplicaremos la PROYECCION que nos dará
el resultado buscado (calificación).
4. Y así quedaría nuestro árbol:

universidad estudiante solicitud

Este árbol es exactamente equivalente a la expresión escrita linealmente como


venimos haciendo:

( ∧ (
⋈( ⋈ ))
2.11 RESUMEN FINAL

Conceptos básicos

 El nombre de una relación, es una consulta de algebra relacional, de hecho es


la consulta más simple que se puede formular
 Este lenguaje utiliza los operadores para combinar, filtrar y dividir relaciones
o SELECCIÓN, PROYECCION, PRODUCTO CARTESIANO, UNION,
DIFERNCIA, RENOMBRAR
o También tenemos algunos operadores que no incluimos en la base del
lenguaje, ya que en realidad son métodos abreviados, es decir, su
función se puede implementar utilizando los operadores básicos. Estos
métodos abreviados son: UNION NATURAL, UNION THETA y
30

INTERSECCION.
Página
 Uso de paréntesis: Es necesario utilizar paréntesis para delimitar el rango de
actuación de los distintos operadores, eliminando así las posibles situaciones
ambigüedad.

CONCLUSION: El álgebra relacional es un lenguaje formal, basado en conjuntos,


operadores de conjuntos y otros operadores que se utilizan para combinar datos de
diferentes relaciones; toma como parámetro de entrada o input, relaciones y produce
como como resultados o salidas nuevas relaciones; Y constituye la base formal de los
sistemas de gestión de bases de datos implementados.

SOLUCIÓN DE LOS PROBLEMAS PLANTEADOS EN LA PÁGINA 15:

El problema 1, es fácil de solucionar en realidad. Podemos lanzar una selección


sobre el resultado anterior imponiendo como condición, que el uNombre1 sea distinto
de uNombre2.

( ( , , ( )
⋈ ( , , ( ))

El problema 2, también puede resolverse de una forma muy inteligente y sencilla.


Basta con sustituir la condición del operador SELECCIÓN, como se muestra:

( ( , , ( )
⋈ ( , , ( ))

31
Página
CURSO DE INTRODUCCIÓN A BASES DE DATOS
Profesor: LUIS ICHAICOTO BONCANCA

Rev.: 01, 25-Enero-2021

TEMA 3: EL LENGUAJE SQL

PORTADA
1. Introducción a SQL

El lenguaje SQL, al igual que el modelo relacional, lleva varias décadas de existencia.
Y es el pilar de un mercado multimillonario. El nombre se puede pronunciar de dos
formas, deletreando (S.Q.L) o leyendo (SIKUEL). Utilizaremos ambas.
SQL está soportado por los principales sistemas de bases de datos comerciales, es un
lenguaje que lleva existiendo desde mucho tiempo atrás, y es un lenguaje
estandarizado. Su estandarización comenzó siendo relativamente simple, pero con el
paso del tiempo, ha evolucionado bastante; hasta tal punto que las versiones
actuales del estándar SQL contienen miles de páginas, pero la esencia del lenguaje,
que es el objetivo de aprendizaje en este tema, sigue siendo relativamente simple.
Nos basaremos en el estándar SQL 2.0, también conocido como SQL 92, junto con
algunas funciones del estándar SQL 3.0.
El lenguaje se puede utilizar en un SGBD de forma interactiva mediante interfaz
gráfica de usuario (GUI) o mediante línea de comandos; pero el uso más frecuente
es mediante la incrustación de sentencias SQL en el código fuente de los programas
que hacen uso de alguna base de datos.

- Uso interactivo de SQL: El usuario teclea consultas SQL o comandos y la


interfaz devuelve resultados. Esta es la forma en que lo utilizaremos para
las demostraciones de este curso.

Por último, SQL es un lenguaje declarativo, es decir, el usuario del lenguaje sólo debe
escribir consultas bastante sencillas que expresan con claridad lo que quiere obtener
de la base de datos sin la necesidad de describir el procedimiento para obtenerlo; y
se trata de un lenguaje basado en los conceptos del algebra relacional.

La naturaleza declarativa de SQL da lugar a que el optimizador de consultas del


SGBD sea un componente extremadamente importante del sistema; pues la misión
del optimizador de consultas en un SGBD es tomar una consulta planteada por el
usuario, y determinar la mejor (en términos de eficiencia y rapidez) forma de
ejecutarla.

Terminología y algunos comandos del lenguaje SQL

El lenguaje SQL consta de dos partes:

- Lenguaje de definición de datos (LDD): Incluye comandos para crear


tablas, eliminar tablas; Y para crear/eliminar otros componentes de una
base de datos que estudiaremos más adelante, por ejemplo las vistas y los
índices.

- Lenguaje de manipulación de datos (LMD): Es el lenguaje que utilizamos


para consultar y/o modificar los datos de la BD. Para consultar la base de
datos, el lenguaje cuenta con el comando SELECT, y para modificar,
cuenta con los comandos INSERT (insertar), DELETE (eliminar), UPDATE
(actualizar); existen varios comandos adicionales como: índices,
restricciones, vistas, disparadores, transacciones, autorización, etc. Que
33

estudiaremos conforme avanzamos en el tema.


Página
Por ahora, hagamos un análisis un poco más detallado del comando SELECT,
que es en realidad el comando central de este lenguaje y el que utilizamos
para consultar la base de datos.

Estructura básica de una sentencia SELECT:


SELECT A1, A2, …, An ( ( × …× )
, ,…
FROM R1, R2, …, Rm
WHERE condición Equivalencia de la sentencia SELECT básica en algebra relacional

Como podemos ver, una sentencia de selección está formada por tres
cláusulas básicas: la cláusula SELECT, la cláusula FROM y la cláusula
WHERE; El mejor orden para entender estas cláusulas es (1) FROM, (2)
WHERE y (3) SELECT.

La cláusula FROM: Identifica las relaciones o tablas sobre las que queremos
consultar; la CONDICION se utiliza para combinar y filtrar las tablas y
finalmente la cláusula SELECT nos dice que hay que devolver como resultado.

Conclusión:

El lenguaje SQL es bastante prominente, soportado por los principales sistemas de


bases de datos comerciales.

Ha alcanzado la estandarización con el paso del tiempo, incorporando en cada


revisión, nuevas características.

Se puede trabajar con SQL tanto de forma interactiva o a través de programas,


mediante la incrustación de código SQL en el código fuente de dichos programas.

Se trata de un lenguaje declarativo de alto nivel, cuyas bases proceden del algebra
relacional.

2. Fundamentos de la consulta SELECT

Como recordaremos de páginas anteriores, el comando SELECT realiza la selección


de un conjunto de atributos SELECT (A1, A2, …, An) procedentes de un conjunto de
relaciones FROM (R1, R2,…,Rm), los cuales satisfacen una determinada WHERE
(CONDICIÓN).

Para el estudio del lenguaje SQL, procederemos de forma práctica realizando


demostraciones sobre la base de datos imaginaria sobre admisiones de estudiantes a
universidades, que ya conocemos y cuyo esquema reproducimos a continuación.
34
Página
Universidad (uNombre, provincia, matricula)
universidad
uNombre Provincia matricula

Estudiante (eID, eNombre, Calificacion, cInstituto)

estudiante
eID eNombre calificacion cInstituto

Solicitud (eID, uNombre, Especialidad, decision)


solicitud
eID uNombre especialidad decision

Los atributos subrayados son las respectivas claves de dichas relaciones, es decir,
Los nombres de Universidad (uNombre) son únicos, la identidad de cada estudiante
(eID) es única y la solicitud de una especialidad en una universidad concreta solo
puede hacerse una vez por cada estudiante (Ej. un estudiante solo puede tener una
única solicitud de la especialidad de mecánica en la UNGE).
A continuación se muestra una instancia del contenido de las tablas de nuestra base
de datos:

35
Página
Página 36
Bien, con toda esta información, vamos a proceder a las demostraciones formulando
diferentes consultas de ejemplo, que a la vez nos irán enseñando las diferentes
características del lenguaje SQL.

Consulta 1: Encontrar la identidad, el nombre y la calificación de todos los


estudiantes con una calificación por encima de 9.0
Se trata de una consulta muy sencilla, con la estructura básica SELECT-FROM-
WHERE; donde en la cláusula FROM indicamos el nombre de la tabla en la que
vamos a buscar la información, en la cláusula WHERE indicamos la condición de
filtrado y en la SELECT indicamos los atributos que queremos obtener.
Al formular y ejecutar dicha consulta en el motor de SQLite, obtenemos el siguiente
resultado:
37
Página
OBSERVACION: No es necesario incluir el atributo Calificación entre los resultados,
aunque sea la condición de nuestro filtro. De hecho, obtenemos el mismo resultado,
sin incluir dicho atributo.

Consulta 2: Queremos una lista que muestre los nombres de estudiantes y junto a
las especialidades solicitadas por dichos estudiantes.
Como podemos deducir, esta consulta combina dos tablas o relaciones, la tabla de
estudiantes y la tabla de solicitudes; básicamente se pide todos los registros de la
tabla solicitudes, pero ya que nos piden también el nombre de los estudiantes,
estamos obligados a incluir la tabla estudiantes (es la que contienen los nombres de
estudiantes).
Formulemos esta consulta por partes:
En la sección SELECT, indicamos los atributos que nos pide la consulta: eNombre,
especialidad.
En el FROM, indicamos las tablas o relaciones implicadas: estudiante y solicitud; y
finalmente,
En el WHERE, formulamos la condición de filtro. Estudiante.eID = solicitud.eID; Se
trata de una condición de unión que nos dice: Queremos combinar tuplas de la tabla
estudiantes con tuplas de la tabla solicitud que tengan el mismo valor en el atributo
eID de ambas tablas. Esta condición, es lo que ocurre de forma automática en la
unión natural que estudiamos en algebra relacional; pero en SQL, siempre tenemos
que expresar la condición de unión natural de forma explícita. Y este es el resultado
al ejecutar la consulta en el motor de SQL.
38
Página
OBSERVACIONES:

1. Como era de esperar, obtenemos los 36 registros


o tuplas de la tabla solicitud. Y el resultado solo
presenta la columna eNombre que proviene de la
tabla estudiantes, junto a la columna
Especialidad que proviene de la tabla solicitud.

2. Observamos algunos valores duplicados, esto se


debe a la naturaleza multi-conjunto de SQL,
como ya explicamos al estudiar el álgebra
relacional. Probablemente se trata de
estudiantes que han solicitado la misma
especialidad en dos universidades diferentes,
pero a efectos de lo que nos pide la consulta, solo
nos interesa la especialidad solicitada, y nos
basta con una copia de cada solicitud múltiple.

Bien, si queremos deshacernos de los valores duplicados, SQL proporciona una


forma conveniente de lograrlo. Simplemente debemos añadir la palabra clave o
modificador “DISTINCT” a la cláusula SELECT (SELECT DISTINCT)
39 Página
OBSERVACION: Con los duplicados
eliminados, pasamos de 36 a 30
tuplas. Se han eliminado las 6 copias.

Consulta 3: Encontrar (nombre, calificación y decisión de sus solicitudes) de


estudiantes que hayan asistido a institutos con capacidad inferior a 1000
alumnos y que hayan solicitado la especialidad de CS en la universidad
Stanford.
Como vemos, es una consulta más complicada que las dos anteriores, implica dos
tablas, por lo que llevará una condición de unión para combinar ambas tablas, y hay
que aplicar un filtro con tres condiciones (cInstituto < 1000, especialidad = ‘CS’ y
uNombre=’Stanford’).
El resultado de ejecutar esta consulta es el siguiente:
40
Página
Consulta 4: Encontrar las grandes universidades que tengan alguna solicitud en
la especialidad CS. Se considera “grande” a las universidades con matricula
superior a 20000.
En esta ocasión, las tablas implicadas son (universidad y solicitud) por lo que irán en
la cláusula FROM, también tenemos que imponer la cláusula WHERE, la condición
de unión para garantizar que nos referimos a la misma universidad en ambas tablas
y añadir las dos condiciones sobre los atributos matricula de la tabla universidad y
especialidad de la tabla solicitud; y finalmente indicar en el SELECT lo que queremos
como resultado (uNombre, el nombre de dichas universidades “grandes”).

Al ejecutar esta consulta de la forma planteada, nos devuelve error (lo sabemos por la
línea ondulada roja que subraya toda la consulta). Este error es causado por el
atributo indicado en el SELECT. Se trata de un problema de ambigüedad, ya que
existe el atributo uNombre en las dos tablas implicadas, SQL exige que se especifique
siempre cuál de los dos atributos se desea; para ello, basta con añadir como prefijo
del atributo, el nombre de la tabla a la que pertenece, por ejemplo,
universidad.uNombre (al tratarse del mismo atributo, con mismo valor, nos dará
igual, pero SQL exige que se indique de forma explícita).

Observación: De nuevo tenemos


valores duplicados, que podemos
eliminar con el modificador distinct
(SELECT distinct).
41

Consulta 5: Encontrar la identidad de estudiantes, sus nombres, su calificación,


universidad donde han solicitado y la matricula de dicha universidad.
Página

Esta consulta implica unir todas las tablas de nuestra base de datos por lo que en
nuestra cláusula FROM aparecerán las tres tablas, y en el filtro WHERE, debemos
añadir condiciones que nos garanticen que entre la tabla solicitud y estudiante, nos
referimos siempre a un mismo estudiante y entre la tabla solicitud y universidad, nos
referimos siempre a la misma universidad.

OBSERVACION: El orden de los


resultados en SQL, es aleatorio.
Así lo permiten las
especificaciones del lenguaje,
de modo que podemos ejecutar
una consulta hoy, y obtener
resultados en un orden
determinado y mañana la
misma consulta podría mostrar
los mismos resultados con un
orden diferente.

42
Página
Cuando el orden es importante para nosotros en nuestro resultado, el lenguaje SQL
proporciona el modificador ORDER BY + nombre_atributo+sentido de ordenamiento
(ascendente ASC ó descendente DESC) que permite ordenar los resultados en base a
un atributo o grupo de atributo. Por ejemplo, si queremos ordenar los resultados de
la consulta anterior en orden descendente del valor de calificación, añadiríamos la
cláusula order by calificación desc.

OBSERVACION: En SQL, Las cláusulas pueden ir


tanto en mayúsculas como en minúsculas.
Igualmente, los atributos pueden ir tanto en
mayúsculas como en minúsculas. Es siempre
recomendable conocer la versión del lenguaje
SQL que se utiliza ya que algunas versiones
pueden diferenciar entre mayúsculas y
minúsculas.
43
Página

OBSERVACION: Se ha omitido el resto de la tabla de


resultados
Si quisiéramos además del ordenamiento por calificación descendente, añadir orden
por matricula ascendente, sería:

OBSERVACION: Si omitimos el sentido


de ordenamiento, por defecto, SQL
aplicará orden ASC.

EL OPERADOR LIKE
Es un operador integrado en SQL que nos permite hacer comparaciones de cadenas
de texto sobre valores de atributos. Por ejemplo, si deseamos conocer la
identificación y la especialidad elegida por estudiantes que han solicitado
especialidades que contengan la cadena “bio”, sería:

OBSERVACION:

1. Cuando no tenemos riesgo de


ambigüedad, no anteponemos el
nombre de la tabla.

2. El símbolo % indica cualquier


texto en la posición donde se
encuentra. Por lo tanto %bio%
quiere decir,
cualquier_texto+bio+cualquier_te
xto. Donde cualquier texto puede
ser también 0 o ningún texto.
44
Página
EL OPERADOR * (asterisco)
En SQL, cuando queremos determinados atributos en el resultado, los ponemos
explícitamente en la cláusula SELECT. En los casos en los que queramos todos los
atributos de una expresión, entonces SQL proporciona el operador ASTERISCO (*)
para tal fin.

OPERACIONES ARITMETICAS EN CLAUSULAS SQL


Con la siguiente consulta vamos a mostrar la habilidad que tiene SQL permitiendo la
realización de cálculos aritméticos en sus cláusulas. Vamos a seleccionar todos los
atributos de la tabla estudiantes sin aplicar ningún filtro, pero sí vamos a añadir una
columna que nos calcule el porcentaje sobre 10 de la nota del estudiante.

OBSERVACIÓN: Vemos que el atributo calculado tiene un nombre aritmético, si no nos gusta dicho
nombre, podemos cambiarlo mediante el operador “as”, como se muestra a continuación:
SELECT eID, eNombre, calificacion, cInstituto, (calificacion/10)*100 as porcentaje
FROM estudiante; PARA TABLAS Y OPERADORES DE CONJUNTOS
3. VARIABLES
45

En este apartado, seguiremos estudiando más características del lenguaje SQL a


través de ejemplos y demostraciones.
Página
Tras estudiar la estructura básica de la sentencia SELECT, vamos a introducir dos
herramientas del lenguaje SQL que nos permitirán construir consultas aún más
expresivas y potentes.
En primer lugar, veremos las variables para tablas, éstas se sitúan en la cláusula
FROM y sirven a dos propósitos: Por un lado se utilizan para mejorar la legibilidad de
las consultas o queries, y por otro, se utilizan para renombrar (cambiar el nombre) de
las tablas o relaciones que aparecen en la cláusula FROM, particularmente cuando
necesitamos operar con dos instancias de una misma tabla.
En segundo lugar, estudiaremos una serie de operadores, los mismos operadores de
conjunto estudiados en el tema de algebra relacional, que en SQL, se conocen con los
nombres UNION (operador unión), INTERSECT (operador intersección) y EXCEPT
(operador diferencia).
Comencemos con los ejemplos demostrativos.
Ejemplo 1: demostración del uso de variables para tablas.
Consulta 1: Mostrar una lista con información de estudiantes que incluya los
siguientes atributos: identidad del estudiante, su nombre, su calificación,
universidades donde ha solicitado y el precio de matrícula de dichas
universidades.
Como podemos deducir, la formulación de esta consulta, implica utilizar todas las
tablas de nuestra base de datos de esta forma:

El resultado de esta consulta no es lo que nos interesa demostrar, por tanto vamos a
modificar esta consulta para demostrar el uso de las variables para tablas, la
consulta anterior quedaría de la siguiente forma:

Como podemos observar, las tablas pueden ser renombradas en la cláusula FROM
con el nombre que nos interese (lo que se conoce como un ALIAS), y podremos
utilizar dicho nombre en las otras secciones de la consulta (SELECT y WHERE). En
el ejemplo, la tabla estudiante se está renombrando con la variable E, la tabla
universidad con la variable U y la tabla solicitud, con la variable S.
El uso de estas variables, nos permite ahorrar tiempo ya que no tenemos que escribir
el nombre completo de la tabla para referirnos a ella. Pero el resultado de esta
consulta reescrita, es exactamente igual al de la consulta original.
Ahora veamos una aplicación de utilidad de estas variables.
Consulta 2: Queremos encontrar todos los pares de estudiantes que tengan la
misma calificación.
Para formular la consulta 2, necesitamos dos instancias de una misma tabla (la tabla
46

estudiante), de esta forma, podemos hacer el producto cartesiano de estas dos


instancias, con lo que estaremos considerando todos los posibles pares de
Página

estudiantes (incluyendo cada estudiante consigo mismo).


RESULTADO:

47
Página
OBSERVACION: La consulta tal como se ha formulado, incluye cada estudiante pareado consigo mismo
debido a que existe el estudiante en las dos instancias de la tabla. Si no nos interesa ver cada estudiante
consigo mismo se puede corregir la consulta añadiendo una condición que diga que el estudiante de la
instancia 1 debe ser distinto al estudiante de la instancia 2.
48
Página
OBSERVACION: Al imponer la condición de
E1.eID distinto (<>) de E2.eID, la cantidad de
resultados se ha reducido bastante. Pero
seguimos teniendo un fenómeno que puede
no ser lo que queremos como resultado,
pues estamos obteniendo resultados
alternativos como NVO NCHAMA---
PANADES MENEJAL y luego PANADES
MENEJAL---NVO NCHAMA, que básicamente
nos dan la misma información. Pero este
problema es de fácil solución, basta con
cambiar el operador distinto (<>) por el
operador menor que (<).

Ahora veamos los operadores de conjuntos.

OPERADOR UNION

Consulta 1: Generar una lista de nombres de estudiantes y nombres de


universidades.

En el lenguaje SQL, el operador unión es la palabra inglesa “UNION” y la consulta


anterior quedaría formulada como sigue:

RESULTADO (los 20 primeros valores):


49
Página
OBSERVACIONES: En la consulta anterior, podemos ver que el lenguaje SQL
permite unir ambos conjuntos aunque el esquema no sea el mismo (como era
requisito en el álgebra relacional), y vemos que el motor SQL ha decidido utilizar
como nombre del atributo para la lista generada, el atributo eNombre y no uNombre.
Esto es un comportamiento que no podemos controlar, pero si podemos definir un
nombre para el conjunto resultante mediante el uso del operador “AS” para
renombrar los esquemas de cada conjunto, y la consulta quedaría reformulada así:

OBSERVACIÓN: Si nos fijamos, los resultados aparecen ordenados, aunque no


hayamos especificado un criterio de ordenación como hemos visto anteriormente
(cláusula ORDER BY y operadores ASC y DESC). Se debe a que el operador UNION
en esta versión de SQL (SQL Lite), por defecto ordena los resultados de forma
ascendente y elimina valores duplicados; es posible que otras versiones del
lenguaje SQL no hayan sido implementadas de esta forma.

Si nos interesa retener los valores duplicados, en lugar de UNION, tenemos UNION
ALL, que si es un operador multi-conjunto. Y veremos que el resultado aparecerá
desordenado y con los valores duplicados incluidos.

50
Página
OPERADOR INTERSECCION

Ejemplo 1: Generar una lista de alumnos que hayan solicitado la especialidad


de CS (Ciencias de la Computación) y también hayan solicitado la
especialidad EE (Ingeniería Eléctrica).

Esta consulta se formula fácilmente obteniendo el conjunto de estudiantes que han


solicitado CS, luego el conjunto de estudiantes que han solicitado EE y haciendo la
intersección de ambos conjuntos, sólo nos quedarán aquellos estudiantes comunes a
ambos conjuntos.

Conjunto de estudiantes que han solicitado CS

Conjunto De estudiantes que han solicitado EE

RESULTADO

OBSERVACIÓN: Existen sistemas que no soportan el operador INTERSECCION, o


que simplemente no lo tienen implementado. Como ya vimos en el algebra
relacional, no se trata de un operador primitivo, por tanto su función se puede
conseguir combinando otros operadores, por ejemplo, la siguiente consulta hace
“exactamente” lo mismo:

OBSERVACIÓN: No es exactamente lo mismo, pero tenemos los mismos


estudiantes, y a estas alturas, queda como ejercicio para el estudiante,
averiguar el porqué de estos duplicados y como deshacerse de estos.

OPERADOR DIFERENCIA

Ejemplo 1: Esta vez, queremos el conjunto de estudiantes que hayan solicitado


la especialidad CS y que no hayan solicitado la especialidad EE.

En SQL, el operador diferencia se conoce como EXCEPT, y para nuestra consulta,


como sabemos ya, solo debemos obtener el conjunto de estudiantes que han
51

solicitado la especialidad CS, luego el conjunto de estudiantes que han solicitado EE


Página

y hacer la diferencia del primero menos el segundo conjunto.


Algunos sistemas de bases de datos, no soportan el operador diferencia, y como en el
caso de la intersección, no debe suponer una imposibilidad en el lenguaje. Solo
debemos esforzarnos en encontrar la manera de reformular nuestra consulta con los
operadores básicos disponibles. Pero en este caso concreto, con los operadores
estudiados hasta ahora, NO ES POSIBLE reformular esta consulta sin el uso del
operador EXCEPT, más adelante estudiaremos los operadores que nos lo permitirán.

4. SUBCONSULTAS EN LA CLAUSULA WHERE

Vamos a añadir un nuevo ingrediente a nuestra expresión básica—SELECT (A1,


A2,…, An)-FROM (R1, R2,…, Rn)-WHERE (condición(es))-. Concretamente, vamos
a añadir la posibilidad de utilizar expresiones que contienen sub-consultas en la
sección de la “condición”.

Las sub-consultas son en realidad consultas SELECT anidadas dentro de la


condición o condiciones de la cláusula WHERE.

Como siempre, seguiremos un aprendizaje práctico mediante ejemplos


demostrativos. La base de datos a utilizar, será nuestra ya conocida BD de
admisiones universitarias.

Ejemplo 1: Mostrar la identidad y el nombre de todos los estudiantes que han


solicitado la especialidad de CS (Ciencias de la Computación) en alguna
universidad.

OBSERVACIONES: En la expresión anterior, vemos que la palabra clave para


insertar sub-consultas en la cláusula WHERE es “IN”.

¿Qué hace la expresión anterior?: Primero, se ejecuta la sub-consulta o consulta


interna, esta consulta devuelve una lista de identidades (eID), concretamente las
identidades de los estudiantes que han solicitado la especialidad CS.

Luego, la consulta principal utiliza el resultado de la sub-consulta en su condición


52

de esta forma: Va a proyectar los atributos eID y eNombre tomando los valores o
tuplas de aquellos estudiantes cuyo eID aparece en la lista que nos da la sub-
Página

consulta.
En realidad se puede conseguir el resultado del ejemplo 1 sin utilizar una sub-
consulta. La consulta sería la siguiente:

Como vemos, al formular la consulta de esta forma, aparece la línea roja ondulada,
que nos indica la existencia de un error sintáctico en la expresión. En realidad, este
error ha sido voluntario para recordarles la importancia de evitar la ambigüedad en
nuestras expresiones, cuando tenemos atributos iguales en distintas relaciones. En
este caso, el problema está en el atributo eID, debemos indicar en la sección
SELECT, de qué relación vamos a tomar los valores del atributo ya sea de estudiante
o de solicitud. Al final, de una u otra relación, el resultado será el mismo, pero SQL
exige que se indique explícitamente.

En este resultado, observamos que el número de tuplas es mayor al que obtuvimos


con la sub-consulta. Pero una mirada más cercana nos dice que se trata de valores
duplicados. Como ejercicio, intenta averiguar la causa de estos duplicados y modifica
la expresión para que desaparezcan los valores duplicados.

***Notar que hay dos estudiantes diferentes con el nombre Craig, el 345 y el 543.
Por lo que al eliminar duplicados, Craig no se considera duplicado por el atributo
eID. ***

Ejemplo 2: Mostrar los nombres de los estudiantes que hayan solicitado la


especialidad CS.

Este problema es muy similar al anterior, salvo que en este caso, solo estamos
interesados en el nombre y no en la identidad.

Observación: Ahora vemos que seguimos teniendo los mismos 5 resultados que
obtuvimos en el ejemplo 1 con la sub-consulta. Pero en este caso, al tener solo el
nombre, Craig ahora se ve como un verdadero duplicado; si añadimos el operador
DISTINCT, nos quedaremos con un Craig, a pesar de que internamente existen
dos estudiantes diferentes con ese nombre.
53
Página
Veamos ocurre al reformular la expresión anterior sin el uso de la sub-consulta:

Si observamos bien, en el resultado original, quedaba claro que Helen se


repetía y se trataba de la misma estudiante con eID=987, mientras que Craig se
repetía siendo dos estudiantes diferentes.

Al aplicar el operador DISTINCT para eliminar duplicados, estamos perdiendo


información sobre cuantos estudiantes de nombre Craig han solicitado CS. De
allí la importancia de tener cuidado con los valores duplicados.

Veamos un caso que demuestra la importancia de los valores duplicados

Ejemplo 3: Mostrar la calificación de los estudiantes que han solicitado la


especialidad CS.

Ahora, reformulemos esta consulta sin la sub-consulta

OBSERVACION: Si queremos calcular el promedio general de las calificaciones de estos


estudiantes, con esta consulta reformulada, tenemos el problema de los alumnos duplicados
(aquellos que han solicitado CS en distintas universidades; Uno puede pensar que aplicando
54

DISTINCT ese problema se resuelve, pero, se crea otro problema. En caso de haber alumnos
Página

diferentes con la misma calificación, DISTINCT eliminaría una calificación necesaria para
calcular el promedio correcto. Como vemos, la única forma fiable es mediante la sub-consulta.
Retomemos el ejemplo utilizado para demostrar el operador diferencia, dijimos que
con las herramientas SQL aprendidas hasta entonces, NO ERA POSIBLE reformular
dicha consulta.

Ejemplo 4: Queremos el conjunto de estudiantes que hayan solicitado la


especialidad CS y que no hayan solicitado la especialidad EE.

Ahora que conocemos el operado IN, mencionar que este operador tiene su opuesto
NOT IN que nos permitirá reformular la consulta anterior sin hacer uso de EXCEPT.

OBSERVACIÓN: En realidad, el
operador es IN, y lo utilizamos
para comprobar si un valor
pertenece o no a un conjunto de
valores. Existe el operador
NEGACIÓN conocido como NOT,
que hace lo contrario de la
expresión que lleva delante.
También podríamos aplicar la
“NOT” antes del eID y
obtendríamos el mismo resultado.

Los operadores IN y su negación NOT IN que hemos utilizado hasta ahora, nos han
servido para probar la pertenencia o no de un valor a un conjunto de valores
determinado resultante de una sub-consulta. Veamos otros operadores EXIST y su
negación NOT EXIST para comprobar si una sub-consulta devuelve un conjunto
vacío o no.

Ejemplo 5: Todas las universidades (su nombre y provincia), que comparten


provincia con alguna otra universidad.

EXPLICACIÓN: Viendo la tabla de universidades de nuestra BD, el resultado


esperado de la consulta a formular sería: [UNGE, BASUPU, RIABACOL,
SIPACOTECH, MPA SIPACO], asociados a Bioko Norte y [STANFORD, BERKELEY]
asociados a California (CA).
55

Referencia correlativa: Es una referencia hecha desde una sub-consulta, tal que, el
valor referenciado pertenece a la consulta principal. La siguiente consulta utilizará
Página

este concepto.
OBSERVACIONES: La expresión formulada utiliza el concepto de Referencia
correlativa antes definido. Vemos que en la sub-consulta se hace una
comparación de igualdad entre atributos provincia de las instancias U1 y U2
de la relación universidad.

En esta expresión: U1 y U2 son dos instancias de la tabla universidad.

Para cada tupla de la instancia U1, se va a ejecutar la sub-consulta que


selecciona el conjunto de universidades que pertenecen a la misma
provincia a la que pertenece la tupla de U1 utilizando para ello la instancia
U2.

El operador EXISTS, comprueba si el conjunto o resultado generado por la


sub-consulta es un conjunto VACIO o NO. En caso de no ser un conjunto
vacío, se añade dicha tupla a los resultados de la consulta principal.
56

***Al observar el resultado obtenido, vemos que no es el esperado. Pues,


Página

tenemos en el resultado todas las universidades posibles (13) mientras que


el resultado esperado es de 7 universidades. ***
La razón por la que la consulta anterior da un resultado incorrecto, es, que la
consulta así formulada con dos instancias de una misma tabla, se comporta de la
siguiente forma:

Supongamos que empezamos por analizar UNGE en la instancia U1, al llegar a la


sub-consulta con el valor de tupla (UNGE, Bioko Norte, 35000) se va a comparar este
valor de la instancia U1 con ese mismo valor de la instancia U2, por lo que vemos
que siempre se va a cumplir la condición de la sub-consulta U1.provincia (UNGE,
Bioko Norte, 35000) = U2.provincia (UNGE, Bioko Norte, 35000); Para resolver este
problema debemos modificar la expresión y exigir con una condición adicional, que el
nombre de la universidad en ambas instancias debe ser distinto (U1.uNombre <>
U2.uNombre). Y, el resultado al ejecutar esta versión es:

OTROS USOS DEL OPERADOR EXISTS

Aunque más adelante estudiaremos operadores aritméticos Y funciones para


encontrar el valor máximo o mínimo de una lista de valores, EXISTS se puede utilizar
para simular una función de máximo o mínimo.

Ejemplo 6: Encontrar la universidad con matricula más alta.

EXPLICACION LA EXPRESION: Tenemos dos instancias de la relación universidad, U1 y U2.


Por cada tupla de la instancia U1, ejecutamos la sub-consulta utilizando como condición el valor
de matrícula de la tupla actual en U1.
El resultado de la sub-consulta es una tabla con todas las tuplas de U2, cuya matrícula sea
mayor que la matrícula de la tupla actual en U1.
Observamos que se trata de un proceso de comprobación de las tuplas de U1 que se detendrá
57

cuando la sub-consulta devuelva un conjunto vacío, es decir, si la tupla de U1 que se está


Página

comprobando tiene el valor de matrícula más alto, entonces la sub-consulta dará como
resultado una lista vacía ya que ninguna tupla de U2 será mayor que dicha tupla de U1.
Ejemplo 7: Encontrar el estudiante con la calificación más alta.

Observación: En este caso, el resultado es ICHAICOTO BONCANCA. Podemos añadir el


atributo Calificación como parte de los resultados para ver la calificación de este
estudiante.

Mencionar que si existieran dos o más estudiantes con la misma calificación, y esa
fuera la más alta, obtendríamos como resultado, los nombres de todos estos
estudiantes.

DESAFIO: Intentar reescribir la expresión anterior sin utilizar sub-consultas

OTRAS PALABRAS CLAVE: ALL y ANY

En algunas versiones de SQL, encontraremos implementados los operadores ALL y


ANY, pero muchos sistemas no soportan dichos operadores, la razón puede ser por el
hecho de que no se trata de operadores básicos, y su comportamiento se puede
lograr reescribiendo las consultas con otros operadores conocidos.

El ejemplo 7 se puede reescribir con el operador ALL de esta forma:

SQLite no soporta los operadores ALL y ANY. Por tanto, no podemos corregir el error
que presenta, pero si podemos ejecutar esta consulta en MySQL y obtenemos el
siguiente resultado:

Ya para practicar, vamos a formular el ejemplo 7 de una manera ligeramente


diferente:

La expresión así formulada devuelve un conjunto vacío como resultado. Como tarea para el lector, le
58

proponemos analizar la consulta para saber exactamente que hace; y llegar a la conclusión de si el
Página

resultado es correcto o no, y si no es correcto, en que caso podría serlo.


Ejemplo 8: Encontrar la Universidad con la matricula más alta.

Junto a la palabra clave ALL, tenemos ANY, que expresa una condición menos
restrictiva que ALL. Mientras ALL exige que el valor que tiene a la izquierda deba
satisfacer la condición para todos los elementos del conjunto que hay a su derecha;
ANY establece que el valor a su izquierda, cumpla la condición para alguno o algunos
de los elementos del conjunto a su derecha.

La consulta del ejemplo 7, sobre encontrar la universidad con la matricula más alta,
se puede reescribir con ANY formulando una consulta que haga lo siguiente: Buscar
la universidad cuya matrícula no sea inferior a alguna de las matrículas.

Ejemplo 8: Encontrar todos los estudiantes que no pertenezcan al instituto más


pequeño de la base de datos.

Como ya mencionamos, algunos sistemas de bases de datos no tienen soporte para


los operadores ALL y ANY. Pero, esto no limita la potencia del sistema, ya que
siempre podemos reformular la consulta utilizando EXISTS y su negación para
conseguir el mismo resultado, en el caso del ejemplo 8, la misma consulta escrita
con EXISTS queda así:
59
Página
Ejemplo 9: Queremos el conjunto de estudiantes que hayan solicitado la
especialidad CS y que no hayan solicitado la especialidad EE.

Para concluir este apartado, vamos a reescribir la consulta del ejemplo 4, esta vez
utilizando el operador ANY.

Ejecutando esta consulta, obtenemos un resultado diferente al obtenido en el


ejemplo 4. Y esto se debe a que existe un error en la formulación, vamos a analizar e
interpretar la consulta anterior:

La consulta dice:

Seleccionar la identidad y el nombre de estudiantes tal que

a) El eID del estudiante sea igual a algún eID del conjunto de identidades (eIDs)
que han solicitado la especialidad de CS, que llamaremos lista (1).
b) Y además, que el eID sea distinto a alguno de los eIDs de del conjunto de
estudiantes que han solicitado la especialidad de EE, que designaremos como
lista (2). Este segundo punto sí está mal formulado, ya que lo común será
encontrar algún estudiante que haya solicitado EE que no sea el estudiante
cuyo eID estamos analizando.

Ej. Puede existir un estudiante que ha solicitado INFORMATICA y EE, por tanto, este
aparecerá en la lista (2), y ante un estudiante que ha solicitado CS Y MECANICA,
cumplirá la condición B, ya que eID del solicitante de INFORMATICA y EE, será
distinto al eID del solicitante de CS y MECANICA.

Este ejemplo 9, es para hacerle reflexionar y entender que a menudo es bastante


difícil utilizar ANY y ALL y dar con la respuesta correcta al primer intento, sobre todo
si no es posible determinar el resultado observando los datos rápidamente.

La formulación correcta del ejemplo 9 con ANY es la siguiente, y queda como


ejercicio para el lector, entender y explicar lo que hacer la consulta realmente.
60
Página
5. SUBCONSULTAS EN LAS CLAUSULAS FROM Y SELECT

Ya hemos hecho una introducción a las sub-consultas en el capítulo anterior, nos


habíamos limitado a utilizarlas en la cláusula WHERE como parte de la condición de
filtrado, formulamos sub-consultas (expresiones SELECT) que generaban conjuntos
de datos que luego utilizamos para las comparaciones. En este capítulo, veremos la
posibilidad de integrar sub-consultas en las cláusulas FROM y SELECT.
El uso de sub-consultas en la cláusula FROM, implica ejecutar una sentencia
SELECT anidada que generará una de las relaciones o tablas a utilizar en la consulta
principal.
El uso de sub-consultas en la cláusula SELECT, implica que estamos definiendo uno
de los atributos que queremos como resultado en la consulta principal. Veamos los
ejemplos demostrativos para estas dos situaciones.

Ejemplo 1: Mostrar los estudiantes tal que al escalar su calificación, la diferencia


respecto a la calificación original es superior a la unidad.
En este ejemplo vamos a escalar la calificación en función de la capacidad del
instituto, es decir: eCalificacion = Calificacion ∗

OBSERVACION: En la consulta formulada, vemos que estamos


escribiendo la expresión que calcula la eCalf hasta tres veces, lo cual es
una posible fuente de errores, ya que podría tratarse de una expresión
matemática mucho más compleja donde fácilmente pudiéramos
cometer un error al redactarla tantas veces. En este caso, nos interesa
simplificar la expresión de alguna forma. En el caso de la cláusula
WHERE, la simplificación resulta bastante sencilla si observamos que las
dos expresiones que comprobamos mayor que la unidad, en realidad es
una forma de expresar la función matemática “valor absoluto”. Por
tanto podemos utilizar la función valor absoluto (ABS) que proporciona
SQL. Esto nos permite eliminar una de las tres copias de la expresión.

Para simplificar aún más la consulta, en aras de evitar escribir múltiples veces la
misma expresión, utilizaremos una sub-consulta en el FROM, que entre otras cosas,
se encargará de calcular la calificación escalada (eCalf).
En la siguiente consulta, vemos la habilidad que tiene SQL al permitirnos hacer
consultas sobre una tabla generada mediante sub-consulta.
61 Página
En esta versión de la consulta, estamos creando una tabla que llamamos C, y que
tiene todos los atributos de la tabla estudiantes (y sus tuplas), además del atributo
calculado eCalf.

El SELECT principal selecciona todos los atributos y tuplas de la tabla C, y aplica un


filtro al resultado, seleccionando solo los valores que cumplen la condición del
WHERE.

También podemos observar como esta vez, solo hemos escrito la expresión
matemática una sola vez. Con lo cual resulta fácil de modificar en el futuro y con
menos probabilidad de cometer errores.

Ejemplo 2: Formar pares Universidad, calificación más alta de solicitantes.

Producto cartesiano

Unión natural

EXPLICACION: La consulta anterior Muestra cada universidad, su provincia y una


calificación que pertenece a la calificación más alta entre las calificaciones de los
estudiantes que han solicitado en dicha universidad.
Para ello primero hace una unión natural como podemos ver en la primera parte. En
la segunda parte (todo lo posterior al segundo AND), hace otra unión natural, esta
vez entre la tabla estudiante y la tabla solicitud, de donde selecciona la calificación
de los estudiantes que han solicitado en la universidad referenciada desde la
consulta principal. La condición establece que se debe buscar la calificación más alta
entre todas las calificaciones de los que han solicitado a dicha universidad.
NOTA: Para entender mejor el funcionamiento de esta consulta, le recomiendo
ejecutar la sub-consulta por separado y ver el resultado de la misma.
Ahora, vamos a ver como reformular la consulta anterior utilizando una sub-
consulta en la cláusula SELECT.
Las sub-consultas en la cláusula SELECT funcionan de la siguiente manera: Se
realiza una operación o cálculo, siempre y cuando dicha operación resulta en un
valor único, dicho valor será utilizado en la tupla resultante de la consulta principal.
62Página
Esta consulta hace lo siguiente: Para cada universidad, muestra el nombre y la
provincia tomados desde la tabla universidad, luego busca la calificación más alta
entre los estudiantes que han solicitado a dicha universidad a través de la sub-
consulta en el SELECT, este valor se asocia al atributo calificación.

Ejemplo 2: Formar pares Universidad, nombre del solicitante con calificación más
alta.
Este problema tiene una solución similar al ejemplo anterior, en lugar de mostrar la
calificación, mostraremos el nombre. Hagamos un primer intento de formular esta
consulta.

OBSERVACIONES: El resultado de la consulta no es consistente, es más en


otros sistemas, esta consulta resulta en un error.

Aquí tenemos que resaltar la importancia de estar seguros que la sub-


consulta en la cláusula SELECT, devuelva un valor único, ya que se utiliza
para completar un atributo de una tupla. Por tanto si devolviese más de
un valor, el sistema no sabría cual elegir para completar la tupla.

En el ejemplo anterior donde lo que completamos era el atributo


calificación, podíamos garantizar la unicidad del resultado de la sub-
consulta al utilizar SELECT DISTINCT, pero en este caso, tenemos varios
SELECT A1, A2,…, An estudiantes solicitando a una misma universidad, y con nombres distintos
FROM R1, R2,…, Rm en general, por lo que, SELECT DISTINCT no es de ayuda.

WHERE condición

6. LA FAMILIA DE OPERADORES JOIN

Volviendo a nuestra estructura SELECT básica, en la cláusula FROM,


acostumbramos a poner una lista de relaciones separadas por comas (,), lo que
equivale “implícitamente” a hacer un producto cartesiano de todas las tablas
indicadas. Ahora vamos a ver la posibilidad de hacer uniones explicitas de tablas en
SQL; las formas de unión (JOIN) que permite SQL son semejantes a las estudiadas
en el álgebra relacional, entre ellas tenemos:
 INNER JOIN ON + [condición]: Equivale a la unión theta del álgebra relacional,
que como ya sabemos, realiza un producto cartesiano de las tablas implicadas
y luego un filtro basado en la condición devolviendo solo las tuplas que
63

cumplen la condición de filtro.


 NATURAL JOIN: Es la unión natural, equivale a la misma unión natural
Página

estudiadas en el álgebra relacional. Como ya sabemos la unión natural hace


un producto cartesiano exigiendo a cada tupla la igualdad de valores entre los
atributos del mismo nombre en las relaciones implicadas; las tuplas que no
cumplen la exigencia son descartadas como parte del resultado. También,
automáticamente se eliminan los atributos duplicados (con el mismo nombre),
conservando una sola copia en el resultado final.
 INNER JOIN USING + [(atributos)]: Similar a la unión natural, pero en este
caso, el diseñador de la consulta especifica los atributos que desea utilizar en
la exigencia de igualdad de valores. Todo esto quedará más claro con los
ejemplos demostrativos.
 [Left | Right | Full] OUTER JOIN: Finalmente tenemos el caso más interesante
de unión, la unión externa con sus tres variantes (Izquierda, Derecha o
Completa). Su funcionamiento es similar a la unión theta o INNER JOIN ON +
condición; la diferencia está en que, los valores que no cumplen la theta-
condición se agregan al resultado rellenando los huecos con valores nulos.
Es importante mencionar que ninguno de estos cuatro operadores añade potencia
expresiva al lenguaje SQL ya que sus resultados se pueden conseguir mediante el
uso de otros operadores primitivos o básicos, pero si su uso resulta a menudo
conveniente debido a que a veces no resulta fácil reformular las consultas para no
utilizar estos operadores.
Bien a continuación vamos a ver los ejemplos demostrativos para conocer el
funcionamiento de estos operadores.

Ejemplo 1: Mostrar una lista de estudiantes y las especialidades solicitadas por


dichos estudiantes.
Esta consulta, anteriormente la formulamos así:

Si pensamos un poco en el álgebra relacional, esta consulta está


haciendo una unión (JOIN) de las relaciones estudiante y solicitud. En
realidad se trata de una unión natural.

Ahora, vamos a reescribir la expresión utilizando el


equivalente a una unión theta en SQL.

Como podemos observar, obtenemos el mismo resultado.

NOTA: En SQL, la unión por defecto es INNER JOIN, por tanto si escribimos
64

sólo JOIN omitiendo el INNER, obtendremos el mismo resultado.


Página
Veamos que ocurre cuando además de la condición theta, contamos con condiciones
adicionales:
Ejemplo 2: Mostrar nombre de estudiante y su calificación, para todos los
estudiantes que vienen de institutos con capacidad inferior a 1000 y que hayan
solicitado la especialidad de CS en la universidad Stanford.
Se trata de una consulta ya estudiada anteriormente y esta fue la expresión anterior
de dicha consulta:

Ahora vamos a reescribir esta consulta utilizando el operador JOIN. Para ello,
eliminamos la coma (que es el producto cartesiano) y en su lugar ponemos JOIN, y
como condición para el JOIN pues, desplazamos la cláusula WHERE, en su lugar,
ponemos ON manteniendo la misma condición de igualdad, y ahora el WHERE, lo
vamos a situar justo antes de la primera condición adicional, y nos queda la
siguiente consulta:

Ahora bien, resulta que podemos prescindir de la cláusula WHERE y añadir las
condiciones adicionales como parte del operador ON, para ello, simplemente
sustituimos WHERE por AND:

OBSERVACIONES: Como vemos, obtenemos el mismo resultado. Puede que alguno se cuestione ¿Qué pongo en
la sección ON y que pongo en la sección WHERE?, pues ambas versiones son prácticamente equivalentes. Pues
la respuesta es:
Primero saber que en SQL existen varias equivalencias entre expresiones, a menudo encontraremos más de una
forma de hacer de conseguir un mismo resultado. En cualquier caso, se espera que el procesador de
expresiones del SGBD sea capaz de ejecutar nuestras expresiones de la forma más eficiente posible.
En el caso particular del operador JOIN, éste suele ser utilizado como una pista sobre como ejecutar la consulta
de esta forma:
Si todas las condiciones están en la sección ON, estamos indicando que a medida que el procesador de consulta
realiza la unión (JOIN), simultáneamente debe evaluar todas las condiciones.
65

Si el resto de condiciones van a la sección del WHERE, entonces el procesador entenderá que la consulta que
Página

afecta a la unión es la que aparece en el ON, y el resto de condiciones se aplican a atributos diferentes
Veamos lo que pasa si tenemos tres relaciones y las queremos unir (JOIN). Esta vez,
vamos a formular la consulta y luego analizarla.
Ejemplo 3: Una consulta que involucra tres relaciones

La interpretación de lo que hace esta consulta queda como ejercicio para el lector. A
continuación, vamos a reescribir la consulta utilizando la unión (JOIN).
Para ello, sustituimos las comas (,) por JOIN, sustituimos WHERE por ON.

La consulta así formulada, falla en algunos SGBD, por ejemplo, en postgres, sin
embargo; se ejecuta sin problemas en el SQLite y en MySQL.
La razón por la que falla en postgres, y posiblemente en otros sistemas, es que
postgres requiere que las uniones sean estrictamente binarias (como establece su
definición fundamental, estudiada en el tema de algebra relacional). Es decir,
debemos delimitar correctamente las sucesivas uniones o JOIN.
Para delimitar, basta con utilizar paréntesis de esta forma:

OBSERVACION: Tenemos que hacer dos uniones o JOINs, para ello, la


primera involucra las tablas solicitud y estudiante con la condición de
igualdad en sus respectivos atributos eID; Podemos observar como el
primer paréntesis recoge toda esta información. El resultado de esta
primera unión, se tiene que unir a la tabla universidad bajo la condición de
igualdad en sus respectivos atributos uNombre, y exactamente lo que se
refleja después del segundo operador JOIN.

Nota: Queremos resaltar un poco más sobre la interacción entre el procesador de


consultas y la forma en que expresamos una consulta en SQL. Los sistemas SQL,
tienden a seguir la estructura de las expresiones cuando hay diferentes operaciones
JOIN delimitadas mediante paréntesis; En el ejemplo anterior decimos: Unir primero
solicitud con estudiante y el resultado unirlo con universidad; típicamente, el
procesador tratará de seguir este orden de ejecución, aunque no tiene por qué
hacerlo así. El lector puede experimentar alterando el orden y observando los
resultados, típicamente se puede observar diferencias en rendimiento (en un
determinado orden, la duración de la ejecución puede ser menor que con un orden
distinto)—En teoría, tales diferencias no deberían existir, ya que el procesador debe
encontrar siempre la manera más eficiente de ejecutar la consulta, pero en la
práctica, sí que sucede; y los programadores suelen afinar el rendimiento de los
sistemas variando el orden del ejecución.
66 Página
Ejemplo 4: Mostrar nombres de estudiantes y sus especialidades solicitadas.
Esta consulta ya fue formulada utilizando INNER JOIN y esta fue la formulación:

Obviamente se trata de una unión natural, que si nos acordamos del álgebra
relacional, la unión natural hace un producto cartesiano entre dos tablas que tienen
atributos de igual nombre y solo conserva como resultado, aquellas tuplas que
tengan el mismo valor en los atributos de igual nombre.
En este ejemplo, las tablas estudiante y solicitud tienen el atributo común eID, por lo
tanto si sustituimos el INNER JOIN por el NATURAL JOIN, entonces, no hace falta la
añadir el operador ON y todo lo que le sigue.

El resultado es el mismo. Además, podemos simplificar un poco más la consulta ya


que con NATURAL JOIN, no es necesario deshacernos de los atributos duplicados
explícitamente, mientras que con INNER JOIN sí; de hecho, con INNER JOIN, si solo
decimos SELECT eID, nos daría error por ambigüedad.

Veamos un ejemplo de NATUAL JOIN con condiciones adicionales


Ejemplo 5: Mostrar nombre de estudiante y su calificación, para todos los
estudiantes que vienen de institutos con capacidad inferior a 1000 y que hayan
solicitado la especialidad de CS en la universidad Stanford.
Esta consulta ya fue formulada con el JOIN de esta forma

Para reformular con NATURAL JOIN, basta con sustituir JOIN por NATURAL JOIN y
eliminar toda la parte del ON.
67
Página
NOTA IMPORTANTE: Existe una característica interesante del operador JOIN en
SQL, de hecho el uso de esta característica se considera mejor práctica que el uso de
la unión natural. Se trata del operador USING (nombre_atributo).
La construcción EXP 1 JOIN EXP2 USING (NOMBRE_ATRIBUTO), permite especificar
explícitamente el atributo común a las dos expresiones que se debe igualar.
Vemos la flexibilidad de este operador respecto a la unión natural donde
automáticamente se igualan todos los atributos del mismo nombre, ya que puede
existir un caso de atributos con el mismo nombre que no tengan el mismo tipo de
información o datos, en un caso así, la unión natural estaría fallando.

Veamos un ejemplo del operador JOIN para dos instancias de una misma relación
Ejemplo 6: Encontrar pares de estudiantes que tengan la misma calificación.
Este problema ya fue resuelto de la siguiente manera

Ahora vamos a reformular esta solución utilizando JOIN… USING.


Para ello, podemos ver que queremos igualar el atributo común calificación, por
tanto podemos eliminar la coma y sustituirla por JOIN… USING (Calificacion) ON…

Como podemos comprobar, a pesar de ser una formulación correcta, nos da un error.
Por experiencia, la mayoría de sistemas de bases de datos no permiten el uso
combinado de USING… + ON…, por lo que si queremos hacer funcionar nuestra
consulta, debemos sustituir la parte de ON… por WHERE…
68
Página
Bien, hasta ahora hemos visto ejemplos con INNER JOIN, NATURAL JOIN y la
cláusula USING. Ahora veamos ejemplos con el miembro más interesante de esta
familia, la unión externa (OUTER JOIN).

Ejemplo 7: Mostrar eNombre, eID, uNombre y especialidad para todos los


estudiantes.
La solución a este problema exige hacer una unión de las tablas estudiante y
solicitud y seleccionar los atributos requeridos para el resultado.

OBSERVACION: La consulta nos da como resultado, la


información requerida en el SELECT, para todos los
estudiantes que han solicitado (aquellos que aparecen
en la tabla solicitud).

El interés del OUTER JOIN, se puede mostrar en el


siguiente caso: Digamos que también queremos incluir
en nuestro resultado, aquellos estudiantes que nunca
han solicitado (no aparecen en la tabla solicitud). – Para
ello, debemos hacer una unión externa por la izquierda
(Los estudiantes que no han solicitado pertenecen a la
tabla a la izquierda del operador JOIN.

*El término izquierda (LEFT) o derecha (RIGHT) se


refiere a la posición de la tabla que contiene las tuplas
que no existen en la otra tabla; LEFT quiere decir,
queremos incluir la tuplas de la tabla que se encuentra
a la izquierda del JOIN pero que no se reflejan en la
tabla que aparece a la derecha del JOIN.
69
Página
OBSERVACIONES: Aquí podemos ver el efecto del
OUTER JOIN, se han añadido algunas tuplas de la
tabla estudiante como por ejemplo los estudiantes
con eID 132 y 160, nunca han solicitado, por eso el
atributo uNombre aparece con el valor NULL.
Dijimos que la unión externa incluirá tuplas que
existen en una de las tablas y no aparecen en la
otra tabla, pero los atributos de dichas tuplas que
pertenezcan a la otra tabla, serán rellenados con
valores NULOS.

Al igual que en el caso del INNER JOIN, se puede


abreviar el OUTER JOIN omitiendo “OUTER”, por
ejemplo LEFT OUTER JOIN equivale a LEFT JOIN.

Desafío: Llegar al mismo resultado del ejemplo sin utilizar el operador OUTER JOIN.
Ejemplo 8: Mostrar eNombre, eID, uNombre y especialidad para todos los
estudiantes, incluir tuplas de la tabla solicitudes aunque no coincidan con tuplas de
la tabla estudiantes.
Este ejemplo es similar al anterior modificado, donde hemos exigido que se
incluyan tuplas de la tabla estudiantes, aunque no coincidan con tuplas de la
tabla solicitudes (sabemos que las tuplas coinciden cuando el atributo común
tiene el mismo valor en ambas tablas).
Por lo tanto, esta vez lo que nos piden es incluir valores de la tabla a la
derecha del OUTER JOIN, para ello, solo debemos cambiar LEFT por RIGHT
(alternativamente, podemos conseguir el mismo resultado cambiando el orden
de las tablas, es decir, a la izquierda colocamos solicitudes y a la derecha
estudiantes; entonces manteniendo el operador LEFT, obtenemos el mismo
resultado.

NOTA: Si resulta que no existen tuplas no comunes en una de las tablas, no se notará
diferencia alguna en los resultados obtenidos.

Ejemplo 9: Mostrar eNombre, eID, uNombre y especialidad para todos los


estudiantes, incluir las tuplas no comunes a ambas tablas.
Ya hemos visto dos casos, LEFT que añade las tuplas no comunes de la tabla a
la izquierda del JOIN y RIGHT que añade las tuplas no comunes de la tabla a
la derecha del JOIN; la pregunta obvia es, ¿Qué hacemos si queremos incluir
tanto las tuplas no comunes de la tabla izquierda y de la tabla derecha?
Esto se consigue con el tercer modificador del OUTER JOIN, que se conoce como
FULL. Con FULL OUTER JOIN, se incluirán las tuplas no comunes a ambas
70

tablas en el resultado.
Página

Desafío: Conseguir el mismo resultado del FULL OUTER JOIN utilizando solo LEFT y
RIGHT OUTER JOIN. Conseguir este mismo resultado sin utilizar la familia JOIN.
Finalmente veamos una importante deficiencia de la familia JOIN. Primero un
breve recordatorio sobre los conceptos de propiedad conmutativa y propiedad
asociativa.
Propiedad conmutativa: Establece que al realizar una operación entre dos
conjuntos u operandos A y B, el orden de estos operandos es irrelevante, es
decir, (A op B) = (B op A).
Propiedad asociativa: Establece que al realizar operaciones entre tres operandos
A, B y C, el orden en que se realizan las operaciones no es relevante y debemos
obtener el mismo resultado, es decir, (A op B) op C = A op (B op C)
Vamos a demostrar el cumplimiento de estas propiedades para la familia
JOIN utilizando este ejemplo sencillo: sean las tablas T1(A, B), T2(B,C) y
T3(A,C)

T1 T1 T1
A B A B A B
11 2 2 3 4 5

Ahora vamos a formular la siguiente consulta

El resultado es:
A B C
1 2 3
4 NULL 5
Ahora formulemos la siguiente consulta

Esta vez obtenemos:


A B C
4 NULL 5
NULL 2 3
1 2 NULL
Con este ejemplo, queda demostrado que el operador FULL JOIN no cumple la
propiedad asociativa. De paso mencionar que tampoco cumplen la propiedad
asociativa los operadores LEFT/RIGHT JOIN. Pero sí, FULL JOIN cumple la
propiedad conmutativa, cosa que no cumplen LEFT/RIGHT JOIN.
Es importante tener en cuenta esta singularidad de la familia JOIN, para no
71

formular consultas que nos den resultados no deseados.


Página

RESUMEN
En conclusión, la familia de operadores JOIN se utiliza en SQL para combinar
relaciones donde explícitamente queremos hacer operaciones típicas del
algebra relacional.
El operador INNER JOIN es el equivalente al THETA JOIN del algebra
relacional, donde se combinan dos relaciones explícitamente utilizando una
condición.
El operador NATURAL JOIN que hace una combinación de dos relaciones
donde implícitamente iguala los atributos con nombres iguales eliminando
una copia del atributo común. Tanto el INNER como el NATURAL se pueden
reescribir de forma similar sin el uso del operador JOIN.
El operador OUTER JOIN, es bastante diferente a los dos anteriores ya que
añade tuplas no comunes a ambas tablas completando los atributos ausentes
con valores nulos.
Los operadores JOIN se utilizan a menudo para indicar al procesador de
consultas cómo debe ejecutar una consulta, y esta característica se puede
utilizar para mejorar el rendimiento de las consultas, aunque en teoría no
debería ocurrir ya que se entiende que el procesador está preparado para
encontrar la forma más eficiente para ejecutar las consultas.

72
Página
7. FUNCIONES DE AGREGACION

Las funciones de agregación generalmente aparecen como parte de la sentencia


SELECT, estas funciones realizan cálculos aritméticos sobre los valores de un
atributo, afectando una o varias filas.

Las funciones de agregación básicas que soporta cualquier sistema SQL son:
 MIN: Devuelve el valor más pequeño o mínimo de un conjunto de valores
 MAX: Devuelve el valor más grande o máximo de un conjunto de valores
 SUM: Devuelve el valor total de la suma de un conjunto de valores
 AVG: Devuelve el valor promedio o media aritmética de un conjunto de valores
 COUNT: Devuelve el número de elementos o valores de un conjunto

Una vez estudiadas las funciones de agregación, ya podremos introducir dos nuevas
cláusulas para la sentencia SELECT de SQL. Se trata de las cláusulas:

 GROUP BY + columnas/atributos: Permite dividir una relación en grupos, de


modo que podremos aplicar las funciones de agregación a cada grupo.
 HAVING + condición: Nos da la posibilidad de aplicar filtros de prueba sobre
los resultados de valores agregados. Mientras que la cláusula WHERE afecta a
nivel de fila o tupla, la cláusula HAVING afecta a nivel de los grupos
generados mediante la cláusula GROUP BY.

Como ya es habitual, procederemos mediante ejemplos demostrativos utilizando la


base de datos de admisiones a universidades. Vamos a empezar estudiando la
función AVG (abreviatura de AVERAGE que significa PROMEDIO).

Ejemplo 1: Calcular la calificación media de todas las calificaciones de la tabla


estudiantes.

La función AVG realiza un promedio de todas las calificaciones que


encuentra en la tabla estudiantes, es decir, suma todas las calificaciones y
divide el resultado entre el número de calificaciones (número de filas de
la tabla estudiantes).

Ejemplo 2: Encontrar la calificación más baja de los estudiantes que han


solicitado la especialidad de CS (Ciencias de la computación).
73
Página
Ejemplo 3: Encontrar la calificación media de los estudiantes que han
solicitado la especialidad de CS (Ciencias de la computación).

Veamos primero la lista de estudiantes que han solicitado la especialidad CS.

Como podemos ver en este resultado, aparecen


alumnos repetidos como (987, Amy) o (124, Amy),
por lo tanto la calificación también aparece repetida;
Al calcular la nota media de esta lista, no estamos
obteniendo información realmente útil, ya que los
valores repetidos afectan al resultado de la media.

Normalmente el cálculo de la nota media que deseamos sería aquel que tenga en cuenta una sola vez
la calificación de cada solicitante de la especialidad CS. Para ello, esta forma de expresar la consulta no
nos ayuda a conseguir dicho resultado.

Tenemos un total de cinco solicitantes de CS, cuyas cinco calificaciones son


(3,4/3,9/3,7/3,5/3,9); Estas calificaciones dan lugar a una calificación media de
[3,68], que es diferente al resultado [3,71] de la consulta anterior; para conseguir el
valor de [3,68]; debemos reformular la consulta para evitar las calificaciones
repetidas por las múltiples solicitudes de la especialidad CS hechas en distintas
universidades por un mismo estudiante.

Para conseguirlo, lo mejor es utilizar sub-consultas en la cláusula WHERE como


vimos anteriormente:
74
Página
Ejemplo 4: Encontrar todas las universidades con matrícula superior a 15000.

Hasta ahora hemos visto ejemplos con las funciones MIN y AVG; El siguiente ejemplo
nos demuestra la función COUNT (contar), que como ya vimos, devuelve el número
de tuplas que cumplen la condición de una consulta.

Observación: Como podemos ver, al lanzar la


consulta sin la función de agregación, obtenemos
11 tuplas que cumplen la condición; por tanto al
añadir la función COUNT, esperamos como
resultado el número 11.

Ejemplo 4: ¿Cuantos estudiantes han emitido solicitudes a la universidad de


Cornell?
Observación: En realidad este resultado
no es del todo correcto.

En realidad estamos contando el número


de solicitudes hechas en Cornell, pero
sabiendo que un estudiante puede hacer
varias solicitudes en la misma universidad,
siempre que sean distintas especialidades;
Por lo tanto, el resultado de esta consulta puede incluir múltiples tuplas de un
mismo estudiante, dando una respuesta mayor que la real. Como nos muestra
la consulta siguiente; que nos muestra todas las solicitudes hechas en Cornell.
75
Página
Como podemos ver, en realidad solo son tres
estudiantes (124, 345 Y 765), pero la consulta
anterior nos daba un total de 6 estudiantes, que en
realidad es el número de solicitudes hechas por tres
estudiantes.

Esta situación también puede resolverse


reformulando mediante sub-consulta; pero veamos
una característica que ofrece SQL para la función
COUNT que nos hará la solución aún más simple:

Si observamos la solución inicial a este ejemplo, utilizamos COUNT (*); como ya


sabemos, el asterisco (*) se utiliza para indicar que se incluyen todos los atributos.
Con la función COUNT, podemos utilizar el modificador DISTINCT y especificar uno
o varios atributos separados por comas así: COUNT (DISTINCT eID).

Desafío: Averiguar lo que hace la siguiente consulta:

Desafío 2: Averiguar lo que hace la siguiente consulta:


76
Página
A continuación veamos la sintaxis y el uso de la cláusula GROUP BY

Ejemplo 5: Número de solicitantes de cada universidad

La cláusula GROUP BY se utiliza siempre en conjunción con una función de


agregación. Y su misión es segmentar una relación en grupos o familias
determinadas por un atributo concreto o conjunto de atributos, por ejemplo, en la
relación de solicitudes, cada universidad puede ser una familia; de modo que se
pueden agrupar las solicitudes por nombre de universidad (uNombre). Con esta
agrupación, podemos aplicar la función de agregación a cada familia (universidad).

OBSERVACION: En esta consulta, se ha segmentado la relación


“solicitud” en grupos identificados por el atributo uNombre, es
decir, cada nombre de universidad es un grupo. Por tanto la
función de agregación COUNT, se tiene que evaluar para cada
grupo y no para cada tupla de la relación. Por tanto en el
resultado solo veremos el nombre de cada grupo en una columna
y en la otra columna, el resultado de evaluar la función COUNT
para cada grupo.

Ejemplo 5: Coste total de la matricula a nivel provincial

Queremos saber con esta consulta, la suma del precio de matrícula de todas las
universidades que pertenecen a una misma provincia. Para ello, tendremos que
agrupar mediante el atributo provincia y evaluar la función de agregación SUM para
cada grupo.
77
Página
Ejemplo 6: Mostrar las calificaciones mínimas y máximas de los solicitantes,
por universidad y por especialidad.

Este ejemplo demuestra un caso más complejo del uso de GROUP BY. Queremos
saber, para cada combinación (Universidad, Especialidad), la calificación mínima y la
máxima de los estudiantes que han solicitado en dicha universidad.

Primero vamos a plantear una consulta que nos permita ver las agrupaciones que
queremos generar:

El resultado esperado de la consulta que vamos a formular con GROUP BY es una


agrupación de las repeticiones de pares (Universidad, especialidad), donde para cada
par, solo se mostrará la calificación máxima y la mínima de los solicitantes. Por
ejemplo en el caso del par (Stanford, CS) esperamos ver solo dos tuplas: (Stanford/
CS/3,9) y (Stanford/CS/3,7).
78
Página
Ahora, supongamos que estamos interesados en conocer el alcance o rango de las
calificaciones para cada par (Universidad, especialidad), es decir, queremos conocer
la diferencia entre la mínima y la máxima calificación; siendo nuestro objetivo final
conocer la combinación que tenga la máxima diferencia.

Vamos a resolver este problema por partes

Primero como sabemos que el resultado de una consulta, generalmente es una


relación, vamos a considerar nuestra consulta anterior como la relación que es y será
el contenido de la cláusula FROM de nuestra nueva consulta:

Como se puede observar, solo hemos hecho un ligero ajuste en los atributos
relacionados con la calificación, a los que hemos renombrado como mn y mx.

A continuación formulamos el SELECT de nuestra consulta como, seleccionar la


diferencia entre mx y mn; y para que la consulta este bien formulada, la expresión
que genera nuestra tabla del FROM, debe tener un alias o nombre de la tabla, que
llamaremos tabla M:

Si observamos el resultado de esta consulta, aparecen varios 0’s (ceros), y es normal,


79

ya que en los casos donde solo ha solicitado un estudiante, la calificación máxima es


Página

igual que la mínima, por tanto, la diferencia es 0.


Ahora, si estamos interesados en la máxima
diferencia, adivina que función nos ayudaría:

Ejemplo 7: Obtener el número de universidades a las que ha solicitado cada


estudiante.

La consulta que vamos a formular en este ejemplo, tiene que hacer la unión de las
tablas estudiante y solicitud; a continuación agrupar las tuplas en función del ID de
estudiante (eID) y finalmente, para cada grupo, presentar el conteo de todas las
universidades asociadas a cada eID.

Vamos a ilustrar el cometido de esta consulta primero, formulando una consulta


similar que ordenará los datos para ver claramente lo que hará nuestra consulta:
80
Página
OBSERVACIÓN: Como podemos observar en los
recuadros, el resultado que nos dará la agrupación
y el conteo será algo como:

eID CONTEO de uNombre


122 2
123 2
124 4
145 2
153 1
234 2
235 1
321 2
345 6
442 2
456 2
543 1
608 2
678 1
765 3
876 3
987 2

81
Página
Ahora veamos algunas sutilezas de la cláusula GROUP BY. Para demostrar la
primera sutileza o comportamiento sorprendente, vamos a añadir a la consulta del
ejemplo 6, otros atributos en el resultado, por ejemplo vamos a añadir además de lo
que ya tenemos (eID y conteo de uNombre), el nombre de cada estudiante:

OBSERVACION: Hemos añadido un atributo que no


forma parte de los atributos de agrupación, y en el
caso del nombre del estudiante, parece no afectar
negativamente a nuestro resultado. Principalmente
porque si vemos la expresión del ejemplo 6 mediante
un ORDER BY, veremos que el nombre es único en
cada grupo, por lo tanto, al agrupar, nos quedaremos
con una copia del nombre para cada grupo. Pero que
pasará para un atributo que no tenga valores únicos
para cada grupo; por ejemplo, si añadimos el
atributo uNombre a los resultados.

OBSERVACION: En el caso del atributo uNombre, vemos que el


sistema selecciona un nombre de universidad para cada eID, pero si
vemos los datos que maneja esta consulta con un ORDER BY y sin la
función COUNT, observaremos que en cada grupo eID, existen
diferentes valores de uNombre; pero el sistema selecciona
aleatoriamente un solo valor de uNombre; Por ejemplo, para 122,
tiene BASUPU y UNILUBA, pero el sistema ha seleccionado BASUPU .

En realidad, en el caso del atributo eNombre también la selección


era aleatoria, solo que al ser un valor repetitivo, siempre selecciona
el mismo valor.

Cabe mencionar que el comportamiento es distinto entre los


82

diferentes SGBD, por ejemplo, en POSTGRES, la consulta nos daría


un error, mientras que en SQL y MYSQL, el sistema selecciona un
Página

valor aleatoriamente.
Veamos otra sutileza, para ello volvamos al ejemplo 7 original, que nos pedía el número de
universidades a las que ha solicitado cada estudiante. Aquí mostramos la formulación de dicha
consulta y su resultado.
OBSERVACION: Pensando un poco, en la tabla
estudiantes existirán estudiantes que todavía no han
hecho ninguna solicitud, por tanto, no aparecen sus eID
en la tabla solicitud; por tanto, dichos estudiantes no
vienen reflejados en los resultados de esta consulta;
evidentemente, no vemos ningún eID asociado con un
conteo igual a 0 (cero).

Y esa es la cuestión, ¿qué hacemos si queremos ver a


estos estudiantes reflejados en el resultado?
83

La respuesta a esta pregunta, queda como ejercicio para


cada lector.
Página
Finalmente, vamos a estudiar la cláusula HAVING, que al igual que GROUP BY, se utiliza siempre en
conjunción con las funciones de agregación.

La cláusula HAVING nos da la posibilidad de aplicar condiciones sobre los resultados de las funciones
de agregación. Se aplica esta cláusula justo después de la cláusula GROUP BY y nos permite probar
condiciones que afectan a cada grupo o agrupación, en contraste con la cláusula WHERE cuya
condición afecta a cada tupla individual.

Ejemplo 8: Obtener una lista de las universidades con menos de 5 solicitudes.

Para formular esta consulta, debemos buscar en la tabla solicitud, agrupar por
uNombre y evaluar una inecuación que tiene por un lado la evaluación de la función
COUNT y por otro lado el valor 5; ambos lados separados por el operador menor que
(<).

DESAFIO: Formular la consulta anterior sin utilizar GROUP BY ni


HAVING.

OBSERVACION: En la mayoría de los casos en que se utiliza GROUP BY


y HAVING, se puede reescribir dichas expresiones sin utilizar ambas
clausulas.

Ejemplo 9: Obtener una lista de las universidades con menos de 5 solicitantes.

OBSERVACION: Este ejemplo es ligeramente diferente al


anterior, ya que en este caso, se está contando el
número de estudiantes que han solicitado a cada
Universidad y dejando en el resultado, solo las
universidades cuyo conteo cumple la condición de ser
inferior a 5.
84
Página
Ejemplo 9: Obtener una lista de las especialidades tal que la máxima
calificación de sus solicitantes está por debajo de la media calculada para la
base de datos.

Para formular esta consulta, primero hacemos la unión de la tabla estudiante y la


tabla solicitud (mediante producto cartesiano), a continuación, agrupamos por
especialidad para poder analizar cada especialidad individualmente. Para cada grupo
(especialidad), obtenemos la calificación máxima de sus solicitantes y comprobamos
si su valor es inferior a la calificación media de la tabla estudiantes.

8. VALORES NULOS

En este apartado, vamos a estudiar los valores nulos en SQL utilizando nuestra ya
conocida base de datos de admisiones a universidades. Y empleando todo lo
estudiado hasta ahora sobre la expresión SELECT (ATRIBUTOS)-FROM
(RELACIONES)-WHERE (condición).

Esta vez, en lugar de estudiar sobre expresiones que podemos escribir en consultas o
queries, vamos a estudiar los datos almacenados.

NULL es un valor especial que, en las bases de datos relacionales, a menos que se
especifique lo contrario, cualquier atributo puede adoptar dicho valor especial. El
valor NULL se utiliza habitualmente para indicar el estado de valores indefinidos o
desconocidos.

Por ejemplo, en la tabla alumnos, se puede registrar un alumno que en el momento


no se dispone de su calificación, por tanto, el atributo calificación utilizará el valor
especial NULL.

Otro ejemplo, es posible crear la relación solicitud, antes de que se tomen las
decisiones; por tanto, el atributo decisión se rellenará con el valor NULL.

A continuación en los ejemplos demostrativos, vamos a estudiar lo que sucede


cuando ejecutamos consultas en presencia de valores nulos, como se comporta el
SGBD en estos casos.

Para ello, hemos agregado dos estudiantes a la base de datos, cuyas calificaciones
85

son desconocidas por ahora y se manifiesta este estado mediante el valor especial
NULL. Veamos los ejemplos demostrativos.
Página
Página 86
Ejemplo 1: Encontrar todos los estudiantes con calificación mayor que 3.5

OBSERVACION: Como podemos ver, no aparecen


los estudiantes Kevin y Lori, ya que su calificación
es NULL, no es posible determinar si tienen
calificaciones mayores que 3.5;

Ejemplo 2: Encontrar todos los estudiantes con calificación menor o igual a 3.5

OBSERVACION: Como podemos ver, no aparecen


tampoco los estudiantes Kevin y Lori, ya que su
calificación es NULL, no es posible determinar si
tienen calificaciones menores o iguales que 3.5.
87
Página
Ejemplo 3: Encontrar todos los estudiantes con calificación mayor que 3.5 o
menor o igual a 3.5

OBSERVACION: En este caso tampoco aparecen los


estudiantes Kevin y Lori. Lo curioso es que la condición
del WHERE, en este caso, siempre se cumple. Ya que
sea cual sea la calificación, siempre será mayor que 3.5
o menor o igual que 3.5; Pero nuestro SGBD omite
dichos valores porque no es capaz de encontrar un
valor numérico para las calificaciones NULL.

Ejemplo 4: Encontrar todos los estudiantes con calificación mayor que 3.5 o
menor o igual a 3.5 o que sean NULL.

OBSERVACION: Ahora si el SGBD ha incluido las tuplas


con calificación NULL.
88
Página
Ejemplo 5: Encontrar todos los estudiantes con calificación mayor que 3.5 o
que pertenezcan a un instituto con capacidad menor que 1600.

OBSERVACION: En este ejemplo,


vemos que el SGBD ha incluido al
estudiante Kevin cuya calificación es
NULL. La razón por la que ha sido
incluido en el resultado, es que sí
cumple la segunda condición - la
capacidad de su instituto es de 1500
alumnos que es menor que 1600.

NOTA: Sin entrar en los detalles técnicos, que puede leer en otras bibliografías, la
evaluación de la cláusula WHERE cuando existen valores NULL, sigue una lógica de
triple evaluación, tal que, cualquier expresión en dicha cláusula puede resultar en
tres valores lógicos: VERDADERO, FALSO o NULL (NULO); Estos valores lógicos son
combinados para producir el resultado final de la expresión, cual es, la decisión
sobre si una tupla debe o no aparecer en el resultado de la consulta.

Finalmente vamos a demostrar mediante ejemplos, la interacción entre el valor


especial NULL y las funciones de agregación ya estudiadas.

No vamos a profundizar sobre este concepto, pero recomendamos ser bastante


cuidadoso al trabajar con funciones de agregación en un entorno donde pueden
existir valores NULL, es necesario que comprendamos el cómo los valores NULL van a
afectar nuestros resultados.
89
Página
Ejemplo 6: Mostrar el conteo del número de estudiantes cuya calificación no
sea NULL.

Obtenemos 25 estudiantes, son todos los estudiantes excepto los


dos que fueron añadidos (Kevin y Lori) para demostrar el
comportamiento de los valores NULL.

A continuación vamos a contar las distintas calificaciones que representan a estos 25


estudiantes:

Obtenemos 19 calificaciones distintas, lo que significa que hay 7 estudiantes que


tienen una misma calificación. Por tanto se omiten las seis copias de dicha
calificación.

Ahora, para saber si la función COUNT DISTINCT incluye o no los valores NULL,
modificaremos la consulta anterior eliminando la cláusula WHERE.

Como podemos observar, tenemos el mismo resultado anterior, lo que significa, que
la función COUNT DISTINCT descarta los valores NULL durante su evaluación.

Finalmente, hagamos una consulta para ver las distintas calificaciones de los
90

estudiantes:
Página
OBSERVACION: Como podemos ver, obtenemos 20
calificaciones diferentes. También observamos que aparece
una calificación NULL. Es decir que la consulta SELECT tiene
en cuenta los valores NULL en su evaluación y presenta los
resultados nulos, si es que existen; mientras que la función
COUNT, descarta directamente los valores NULL en su
evaluación y resultados.

Bueno, estos han sido solo un ejemplo de los efectos que podemos observar al
formular consultas en presencia de valores NULOS, y una vez más recomendamos
ser cuidadosos al trabajar con bases de datos con atributos que admiten valores
NULL, intentando comprender en cada momento el resultado esperado y comparar
con el resultado obtenido.
91
Página
9. SENTENCIAS DE MODIFICACION DE DATOS

En este apartado final, vamos a estudiar las sentencias de modificación de datos que
tiene el lenguaje SQL.

Estudiaremos las sentencias para la INSERCION de datos, sentencias para la


ELIMINACIÓN de datos existentes y sentencias para la ACTUALIZACIÓN de datos
existentes.

INSERCIÓN DE DATOS

Para insertar nuevos datos en cualquiera relación de una base de datos, existen dos
métodos.

MÉTODO DE INSERCIÓN DIRECTA

El primer método permite insertar una tupla en la base de datos, mediante la


especificación de los valores de cada atributo. La sintaxis para este método es:

INSERT INTO Nombre_de_tabla VALUES (Valor_A1, Valor_A2,…, Valor_An)

MÉTODO DE INSERCION MEDIANTE SENTENCIA SELECT

El segundo método es mediante una SENTENCIA SELECT. Este método sustituye la


sección VALUES del COMANDO INSERT INTO por una sentencia SELECT; de tal
forma que, siempre y cuando el resultado de la sentencia SELECT de lugar a una
relación con igual estructura o esquema que la tabla especificada para el comando
INSERT INTO, se podrán insertar todas las tuplas producidas por dicha sentencia
SELECT.

La sintaxis para este caso es:

INSERT INTO Nombre_de_tabla SENTENCIA-SELECT

ELIMINACIÓN DE DATOS EXISTENTES

El comando SQL para eliminar es bastante sencillo y su sintaxis dice:

DELETE FROM Nombre_Tabla

WHERE Condición

Básicamente basta con especificar la tabla y formular la condición, se trata de una


condición similar a las estudiadas en las sentencias SELECT; todas las tuplas que
cumplan la condición especificada, serán eliminadas.

La condición puede ser muy simple o muy compleja, llegando a incluir sub-
consultas, funciones de agregación, etc. Todo ello, vamos a aclararlo mediante los
ejemplos demostrativos.
92
Página
ACTUALIZACIÓN DE DATOS EXISTENTES

Finalmente, para actualizar datos existentes, se utiliza la expresión siguiente:


UPDATE Nombre_Tabla
SET atrib = EXPRESIÓN
WHERE Condición

Como vemos, este commando es similar al commando para la eliminación. Actúa


sobre una tabla, evaluando la condición sobre cada tupla de dicha tabla; de forma tal
que cuando la condición sea verdadera, en este caso en vez de eliminar la tupla, se
modificará el valor del atributo indicado en atrib, asignándole el valor indicado por
EXPRESION.
Cabe mencionar que tanto la expresión como la condición, pueden ser sencillas o
bastante complejas, llegando a tener sub-consultas a otras tablas o a la misma tabla
de la BD.
La expresión anterior solo permite actualizar un único atributo. Si queremos
actualizar simultáneamente varios atributos, la fórmula queda como sigue:
UPDATE Nombre_Tabla
SET A1 = Expr1, A2 = Expr2,…, An = Exprn
WHERE Condición

Bien, ahora que conocemos todas las herramientas del lenguaje SQL para la
modificación de datos, vamos a ver una serie de ejemplos demostrativos para
practicar utilizando dichas herramientas y aclarar posibles dudas.

Para ello, utilizaremos nuestra ya acostumbrada base de datos de admisiones a


universidades.

Ejemplo 1: Inserción directa de una tupla especificando sus valores.

Vamos a añadir a la tabla universidades la tupla con los siguientes valores:

Nombre de universidad = Carnegie Mellon, Estado = PA y matricula = 11500

Primero hagamos una sentencia SELECT que nos muestre todas las universidades
existentes en la tabla, para ver que todavía no existe la tupla que vamos a añadir:
93
Página
Y ahora vamos a formular la sentencia de inserción:

Observación: Al ejecutar la sentencia, no aparece ningún resultado en pantalla como


ocurre con las sentencias SELECT, eso como podemos imaginar, es normal. Debemos
acceder a los datos de la tabla universidad para verificar si se ha agregado nuestra
nueva tupla.

Pero algunas aplicaciones utilizadas para interactuar directamente con los SGBD
suelen ofrecer información en pantalla sobre los comandos ejecutados y los
resultados de los mismos, tal como vemos en la imagen anterior; donde la línea 50,
nos muestra el comando ejecutado y la línea 51, comentarios sobre los efectos que
ha tenido la ejecución del comando.

Vamos a verificar mediante SELECT, la existencia de la nueva tupla en la BD:

Y, efectivamente tenemos una nueva tupla, con los valores


de Carnegie Mellon, PA (Palo Alto), y 11500

94
Página
Ejemplo 2: Hacer que todos los estudiantes que no han hecho ninguna
solicitud, soliciten en la nueva universidad añadida (Carnegie Mellon), la
especialidad CS, y la decisión desconocida (por ahora).

Bien, para esta consulta, vamos paso a paso. Primero formulemos una consulta que
nos muestre todos los estudiantes que todavía no han emitido una solicitud:

Tenemos un total de 10 estudiantes que no existen en la


tabla solicitud porque todavía no han emitido ninguna
solicitud.

A continuación, vamos a transformar la consulta SELECT anterior en una estructura


que construya las tuplas que queremos insertar en la tabla solicitud.

Recordatorio: La tabla solicitud tiene los atributos: eID, uNombre, especialidad,


decisión.

Observación: Como vemos ahora la


consulta SELECT nos devuelve una
relación con igual estructura que la tabla
solicitudes, y con todos los valores que
deseamos insertar en dicha tabla. Ahora
podemos utilizar el segundo método de
inserción.
95
Página
Ejemplo 3: Encontrar solicitantes rechazados de la especialidad EE en otras
universidades y admitir a todos en Carnegie Mellon para EE.

Para este ejemplo, vamos a proceder por partes. Primero vamos a buscar los
estudiantes que han solicitado EE en otras universidades con decisión NO:

Como podemos ver, tenemos dos estudiantes rechazados


para la especialidad de EE, en alguna universidad.

Ahora vamos a componer las tuplas para su inserción en la tabla de solicitudes. Para
ello:

Tomaremos el eID de los resultados de nuestra consulta anterior;

Para el atributo uNombre, tenemos ‘Carnegie Mellon’;

Para la especialidad, tenemos ‘EE’;

Para decisión, tenemos: ‘SI’, ya que según el ejemplo, debemos admitir a los
estudiantes para dicha especialidad.

Lo anterior queda formulado así en SQL:

Y como podemos observar, ya tenemos las tuplas listas


para ser insertadas en la tabla solicitud.
96
Página
Con la consulta SELECT, observamos que
se han añadido las dos nuevas tuplas a
nuestra base de datos.

A continuación vamos a explorar el comando eliminar (DELETE).

Ejemplo 4: Eliminar a todos los estudiantes que han solicitado más de dos
especialidades diferentes.

Vamos a considerar a que un estudiante que solicita más de dos especialidades, nos
es de fiar y por tanto, vamos a eliminarle completamente de la base de datos.

Para resolver este ejemplo, empezamos formulando una consulta que nos muestre
todos los estudiantes que han solicitado más de dos especialidades:

Encontramos dos estudiantes en esta situación.


Ahora vamos a modificar la consulta convirtiéndola
en una consulta de eliminación.
97
Página
Podemos confirmar la eliminacion de los estudiantes 345 y 876 mediante una consulta SELECT a la
tabla estudiantes:

POBSERVACIOIN: Efectivamente hemos


conseguido eliminar las dos tuplas de la
tabla estudiante, pero si vamos a la tabla
solicitud, encontraremos las solicitudes
asociadas a estos estudiantes;

Podemos ejecutar la misma expresión, esta


vez sobre la tabla solicitud para eliminar
dichas tuplas. Pero cabe mencionar que
algunos SGBD no permiten eliminar de una
tabla mediante una sub-consulta sobre la
misma tabla.

Por otro lado, el efecto de eliminar datos en


una tabla, dejando datos asociados a estos
en otras tablas se conoce como ANOMALIA
DE ELIMINACION, algo que estudiaremos en
el tema sobre DISENO RELACIONAL.

OBSERVACION: Cuando el SGBD no permite la eliminación en una tabla que


interviene en la sub-consulta, para poder eliminar, tendremos que crear una tabla
temporal, donde almacenaremos el resultado de la sub-consulta y finalmente ejecutar
el comando DELETE usando la tabla temporal en lugar de la sub-consulta.

Ejemplo 5: Eliminar las universidades que no tengan solicitantes de la


especialidad CS.

Para ello, empezamos con una consulta que nos muestre todas las universidades que
carecen de solicitudes de la especialidad CS:

Para eliminar todas estas universidades, basta con modificar ligeramente la


consulta de SELECCIÓN; simplemente cambiamos SELECT * por DELETE:
98
Página
Finalmente echemos un vistazo a las consultas de ACTUALIZAICION:

Ejemplo 6: Admitir en la especialidad de Económicas, a los solicitantes de


Carnegie Mellon que tengan una calificación menor que 3.6

Para este ejemplo, comenzamos formulando una consulta que nos devuelva todos los
solicitantes de Carnegie Mellon que tienen calificaciones menores que 3.6:

Observamos que hay dos solicitudes a Carnegie Mellon


cuyos solicitantes tienen una calificación menor que
3.6; A continuación vamos a modificar la consulta
anterior y para transformarla en una consulta de
actualización.

Mediante una consulta SELECT, podemos observar los cambios en la tabla solicitud:

99
Página
Página 100

También podría gustarte