Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
El lenguaje SQL
El paso de la gestin automatizada de informacin basada en ficheros a la gestin
basada en el uso de Sistemas Gestores de Bases de Datos (SGBDs) trajo consigo
importantes cambios en el modo de disear, construir e utilizar aplicaciones
informticas. Uno de los cambios ms significativos fue la aparicin de los
denominados lenguajes de consulta: muchos de los primeros SGBDs estaban
acompaados de uno o ms lenguajes desarrollados especficamente para el acceso a la
informacin contenida en las BDs bajo su control. La idea es que esos lenguajes
proporcionan una interfaz sencilla que simplifica el acceso a los datos, descargando
buena parte de la responsabilidad (y la complejidad) del mismo sobre el propio SGBD.
Uno de los primeros lenguajes de consulta de BDs fue el Structured Query Language
(ms conocido por sus siglas SQL), desarrollado por la compaa IBM para SYSTEM R,
un SGBD relacional experimental. Con el paso del tiempo, SQL se ha convertido en un
lenguaje estndar: prcticamente todos los SGBD relacionales del mercado lo soportan,
en mayor o menor medida. De hecho, SQL cuenta ya con varias versiones, resultantes
de sucesivas revisiones, datando la versin ms reciente del ao 1999 (de ah esta sea
conocida como SQL99)
SQL es soportado por los SGBDs relacionales porque est fuertemente vinculado al
modelo relacional: el SGBD da respuesta a cada consulta SQL por medio de la
ejecucin de una secuencia de operaciones del lgebra relacional (el lgebra con los
correspondientes operadores - que el modelo relacional incluye para permitir la
manipulacin de las relaciones).
Los SGBDs suelen incluir entre las herramientas que los acompaan un intrprete de
SQL: se trata de un programa informtico capaz de recibir y evaluar consultas SQL,
conectndose con la BD adecuada, y presentando al usuario los resultados obtenidos. Y
los SGBDs tambin admiten que los programas de aplicacin que necesiten acceder a
una determinada BD le enven sus solicitudes de informacin en forma de consultas
SQL.
-
Instruccin SELECT: permite la recuperacin de informacin
-
Instruccin INSERT: permite introducir nuevos datos en la BD
-
Instruccin UPDATE: permite la actualizacin de datos en la BD
-
Instruccin DELETE: permite la eliminacin de informacin de
la BD
Lenguaje de Definicin de Datos (LDD): SQL permite tambin la definicin y
estructuracin de las diferentes BDs controladas por un SGBD
- Instruccin CREATE TABLE: crea una nueva relacin en la BD.
- Instruccin ALTER TABLE: permite la modificacin de la
estructura de una relacin ya existente en la BD.
- Instruccin DROP TABLE: permite la eliminacin de una
relacin en la BD.
Nombre que
Tipo de datos SQL recibe en Access Operaciones soportadas Ejemplo
NUMBER (numDigitos) Nmerico +,-,*,/ 53
CHAR(numCaracteres) TEXTO (numCaracteres) + (concatenacin) Casa
DATETIME Fecha/Hora 03/09/57
Ejemplo a utilizar
Antes de abordar la descripcin de la instruccin SELECT de SQL, estableceremos el
ejemplo de partida que utilizaremos a lo largo de la explicacin. Se trata del esquema
lgico - relativo a la gestin de una empresa que habamos obtenido al analizar la
transformacin desde el modelo ER al modelo relacional.
Empleado (NSS, NPila, Ap1, Ap2, Sexo, Direccin, FNac, NumDept, NSSSupervisor)
TrabajaEn (NSS, Numero, Horas) LocalidadDpt (NumDept, Loc) Proyecto (Numero, Nombre, Loc, NumDept)
Las relaciones, desde el punto de vista de SQL, deben ser consideradas como tablas;
asumiremos que, como tales, contienen los siguientes datos en un momento dado:
Empleado
NSS NPila Ap1 Ap2 Sexo Direccin FNac NumDept NSSSupervisor
1 Juan Prez Prez H R/ Vilar 2 02/06/64 D01
2 Pedro Lpez Blas H R/ Fontes 12 23/12/50 D01 1
3 Mara Prez Pi M R/ Galicia 6 12/03/75 D02
4 Antonio Botn Castro H Pza Galicia 1 13/01/65 D02 3
Departamento
NumDept NomDept NSS FechaIniGerente
D01 Ventas 1 01/01/2000
D02 Produccion 2 01/01/2004
Proyecto
Numero Nombre Localidad NumDept
V1 Sistema contable A Corua D01
P1 Producto A Ferrol D02
P2 Producto B Ferrol D02
TrabajaEn
NSS Numero Horas LocalidadDpt
1 V1 10 NumDept Loc
2 V1 35 D01 A Corua
3 P1 20 D02 A Corua
4 P1 5 D02 Ferrol
4 P2 30
La instruccin SELECT
La instruccin SELECT de SQL se utiliza para recuperar (realizando un procesamiento
previo, si fuese necesario) informacin de la BD. Se trata de una instruccin que toma
como parmetros de entrada una o mas tablas, y devuelve como resultado una nueva
tabla, generada dinmicamente, que contiene la informacin solicitada. El resultado
puede ser desde una tabla con una nica fila y una nica columna (es decir, un nico
valor) hasta una tabla con mltiples filas y columnas.
En realidad, no todas estas clusulas deben aparecer obligatorias en una consulta Select.
Slo ls clusulas SELECT y FROM son imprescindibles para formar una consulta
Select mnima.
La clusula SELECT
Supongamos que queremos recuperar el NSS y el nombre completo (nombre de pila +
apellidos) de todos los empleados de la empresa. Una consulta que lo permite sera la
siguiente:
Cmo se obtiene esta tabla? Una consulta Select se evala de la siguente manera:
por comas.
- Cada una de esas expresiones ser evaluada sobre cada fila de la tabla
original, dando lugar a una lista de valores atmicos (tantos como
expresiones)
- La lista obtenida servir para crear una nueva fila en la tabla resultado.
- La tabla resultado tendr una columna por cada expresin incluida en la
clusula SELECT
- El nombre de cada columna ser igual a la expresin que la genera.
2 (Resultado: 2)
2+3 (Resultado: 5)
Fede + rico (Resultado: Federico)
Ap1 + Ap2 (Resultado: dada una fila de la tabla original, la
concatenacin de los valores de sus columnas Ap1 y Ap2)
Nombre: + NPila (Resultado: dada una fila de la tabla original, la
concatenacin de la cadena Nombre: y el valor de la fila en la
columna NPila)
- Como ltimo paso, las filas obtenidas se unen para obtener la tabla
resultante:
NSS NPila Ap1 Ap2
1 Juan Prez Prez
2 Pedro Lpez Blas
3 Mara Prez Pi
4 Antonio Botn Castro
La consulta que hemos visto utiliza expresiones en la clusula SELECT que estn
constituidas por simples nombres de columnas. Sin embargo, podemos realizar
consultas ms sofisticadas incluyendo expresiones ms complejas. Por ejemplo,
podemos modificar la consulta anterior para que el nombre completo de cada empleado
aparezca en una nica columna:
En esta nueva consulta, reemplazamos las tres expresiones que se referan a las
columnas de nombre y apellidos de los empleados por una expresin nica, en la que se
utiliza el operador de concatenacin de cadenas (+) para unir los valores de dichas
columnas, separados por espacios y comas: se trata de una expresin en la que se
combinan nombres de atributos y valores constantes ( y , ). La consulta se evaluar
de la siguiente forma:
- Como ltimo paso, las filas obtenidas se unen para obtener la tabla
resultante:
NSS Ap1 + + Ap2 + , + NPila
1 Prez Prez, Juan
2 Lpez Blas, Pedro
3 Prez Pi, Mara
4 Botn Castro, Antonio
Las expresiones complejas no tienen por que utilizar slo atributos o valores de tipo
carcter. La siguiente consulta devuelve el nmero mensual de horas que cada empleado
le dedica a cada proyecto (que se obtienen multiplicando por 4 el nmero de horas
semanal por proyecto, almacenado en la tabla TrabajaEn):
TrabajaEn
NSS Numero Horas*4
1 V1 40
2 V1 140
3 P1 80
4 P1 20
4 P2 120
Valores nulos
El modelo relacional admite el uso de los valores nulos durante la asignacin de
valores a los atributos de una tupla. Eso significa, en la terminologa de SQL, que
podemos encontrarnos con celdas de una tabla que alberguen valores nulos.
Por lo tanto, la clusula SELECT puede involucrar, en sus expresiones, valores nulos (al
evaluar esas expresiones sobre los valores de una fila determinada). La pregunta es
cmo afectan los valores nulos al clculo de expresiones incluidas en una clusula
SELECT? Y la respuesta es sencilla: el valor de un nulo es desconocido; por lo tanto, en
toda expresin en la que intervenga un valor nulo, el resultado ser tambin
desconocido.1 Y en la tabla resultante, el valor desconocido se representar mediante
otro valor nulo.
- 2 + Nulo = Nulo
- Casa + Nulo = Nulo
- NSS 5 = Nulo (si NSS se evala a Nulo)
1
Ya que, si nos falta alguno de los parmetros de la expresin, es imposible determinar el resultado.
Empleado
NSS Npila Ap1 Ap2 NSSSupervisor NSS NSSSupervisor NSS NSSSupervisor
1 Juan Prez Prez ... ... 1 (Nulo) 1
2 Pedro Lpez Blas ... 1 ... 2 1 2 1
3 Mara Prez Pi ... ... 3 (Nulo) 3
4 Antonio Botn Castro ... 3 ... 4 3 4 3
SELECT Loc
FROM LocalidadDpt
Como en los casos anteriores, la consulta se evala recuperando una por una las filas de
la tabla indicada y evaluando las expresiones de la clusula SELECT sobre cada una de
ellas:
LocalidadDpt
NumDept Loc Evaluacin de Loc:
D01 A Corua A Corua
D02 A Corua A Corua
D02 Ferrol Ferrol
Loc
A Corua
A Corua
Ferrol
Como se puede apreciar, una de las localidades aparece repetida: se trata de A Corua,
como resultado de ser obtenida como sede de dos departamentos diferentes. Esto es as
porque SQL incumple la restriccin de clave del modelo relacional, que exige que en
una relacin (una tabla) no puede haber filas repetidas. As, al verse liberado de la
obligacin de comprobar esta restriccin, cualquier intrprete de SQL podr procesar
una consulta mucho ms rpidamente.
Sin embargo, SQL s que permite eliminar filas repetidas en el resultado de una consulta
(aunque provocando, probablemente, un retraso adicional por parte del intrprete en la
obtencin del resultado final). Para hacerlo, la clusula SELECT cuenta con el
modificador distinct: aadiendo este modificador a nuestra consulta...
Loc
A Corua
Ferrol
NumDept NPila
D01 Juan
D01 Pedro
D02 Mara
D02 Antonio
Si bien en la columna NumDept hay varios valores repetidos, no hay ninguna fila
repetida; por lo tanto, la presencia o no de distinct en la consulta no afecta al resultado
final.
SELECT NSS, Npila, Ap1, Ap2, Sexo, Direccion, Fnac, NumDept, NSSSupervisor
FROM Empleado
Para evitar esto, la clusula SELECT admite un carcter comodn, que representa a
todas las columnas de una tabla: el asterisco (*). As, la siguiente consulta sera
equivalente a la anterior:
SELECT *
FROM Empleado
En realidad, nada nos garantiza ese orden: la definicin formal de SQL no nos indica
nada a ese respecto. Adems, la definicin del modelo relacional (que, no lo olvidemos,
es la base de SQL) especifica que una relacin (una tabla) es un conjunto de tuplas:
tratndose de un conjunto, el concepto de orden no es aplicable. A dnde nos lleva
todo esto? Si ejecutamos dos veces una misma consulta, nada nos garantiza que los
resultados aparezcan en el mismo orden las dos veces.
- Para cada fila de la tabla original se calculan los valores de esas expresiones.
- Las filas originales se ordenan de acuerdo a los valores resultantes de evaluar
las expresiones de ordenacin: en primer lugar se tienen en cuenta los
resultados de la primera expresin; se toman despus en cuenta los
resultados de la segunda; y as sucesivamente.
- Los valores resultantes de cada expresin pueden ser ordenados de forma
ascendente o descendente: para ello se utilizan los modificadores ASC (la
opcin por defecto) y DESC.
- Las filas del resultado se ordenan en funcin del orden establecido para las
filas de la tabla original a partir de las que son obtenidas.
Veremos a continuacin dos ejemplos del uso de la clusula ORDER BY para precisar
mejor su funcionamiento.
Empleado
NSS NPila Ap1 Ap2 Ap1 Ap2 NPila
1 Juan Prez Prez ... Prez Prez Juan
2 Pedro Lpez Blas ... Lpez Blas Pedro
3 Mara Prez Pi ... Prez Pi Mara
4 Antonio Botn Castro ... Botn Castro Antonio
- Las filas se ordenan empleando la primera expresin (Ap1), de forma ascendente (la
opcin por defecto):
Empleado
NSS NPila Ap1 Ap2 Ap1 Ap2 NPila
4 Antonio Botn Castro ... Botn Castro Antonio
2 Pedro Lpez Blas ... Lpez Blas Pedro
- Como se puede observar, dos filas (las correspondientes a Mara y Pedro) presentan
en mismo valor para Ap1. Para decidir su orden, recurrimos a la segunda expresin
(Ap2)
Empleado
NSS NPila Ap1 Ap2 Ap1 Ap2 NPila
4 Antonio Botn Castro ... Botn Castro Antonio
2 Pedro Lpez Blas ... Lpez Blas Pedro
1 Juan Prez Prez ... Prez Prez Juan
3 Mara Prez Pi ... Prez Pi Mara
Empleado
NSS NPila Ap1 Ap2 NSS Ap1+ + Ap2 + , + Npila
4 Antonio Botn Castro ... 4 Botn Castro, Antonio
2 Pedro Lpez Blas ... 2 Lpez Blas, Pedro
1 Juan Prez Prez ... 1 Prez Prez, Juan
3 Mara Prez Pi ... 3 Prez Pi, Mara
Ejemplo: Indicar los NSS de todos los empleados de la empresa, ordenados por
departamento y por edad (los ms jvenes primero).
Ordenar por edad, de forma ascendente, implica ordenar por fecha de nacimiento (el
dato que poseemos sobre los empleados) de forma descendente. Por lo tanto, la consulta
a realizar sera esta:
Obsrvese el uso que se hace del modificador DESC para exigir que las filas se ordenen
por fecha de forma descendente (de mayor a menor, en lugar de de menor a mayor)
Empleado
NSS Npila Ap1 Ap2 NumDept FNac NSS NumDept
1 Juan Prez Prez ... D01 02/06/64 1 D01
2 Pedro Lpez Blas ... D01 23/12/50 2 D01
3 Mara Prez Pi ... D02 12/03/75 3 D02
4 Antonio Botn Castro ... D02 13/01/65 4 D02
(Se da la casualidad en el ejemplo que el orden solicitado en origen para las tuplas es
aquel en el que las habamos presentado inicialmente).
las columnas de una tabla nos interesan; mediante WHERE podremos seleccionar
cules de las filas contenidas en una tabla nos interesan. Eso nos permitir, por ejemplo,
restringir cualquiera de las consultas que hemos realizado hasta ahora a los empleados
de un determinado departamento. As, la consulta siguiente permitir obtener el nombre
de todos los empleados del departamento de Ventas.
Para seleccionar las filas que nos interesen, la clusula WHERE va acompaada de un
conjunto de condiciones de seleccin. Slo las filas que cumplan esas condiciones
sern tenidas en cuenta para evaluar la consulta.
Condiciones simples
=
>
<
Expresin1 Expresin 2
<>
>=
<=
La idea es que tanto Expresin1 como Expresin2 se evalen sobre los valores de cada
fila de la tabla original. Una vez evaluados, se comparan. Si la condicin especificada se
cumple, la fila se selecciona. Si la condicin no se cumple, la fila es descartada.
En el caso del ejemplo de la consulta anterior (datos de los empleados del departamento
de Ventas, D01), la evaluacin se hara as:
- En primer lugar, seleccionar las filas a utilizar para calcular el resultado, aplicando
la condicin de seleccin del WHERE
Empleado
NSS Npila Ap1 Ap2 NumDept NumDept D01 NumDept=D01 Fila seleccionada
1 Juan Prez Prez ... D01 ... D01 D01 Verdadero
2 Pedro Lpez Blas ... D01 ... D01 D01 Verdadero
3 Mara Prez Pi ... D02 ... D02 D01 Falso
4 Antonio Botn Castro ... D02 ... D02 D01 Falso
Empleado
NSS Npila Ap1 Ap2 NumDept NSS Ap1 + + Ap2 + , + NPila
1 Juan Prez Prez ... D01 ... 1 Prez Prez, Juan
2 Pedro Lpez Blas ... D01 ... 2 Lpez Blas, Pedro
Otro ejemplo podra ser este: Nombres de todos los empleados de la empresa que hayan
nacido antes que Pedro.
Select NPila
FROM Empleado
WHERE Fnac<23/12/50
Empleado
NSS Npila Ap1 Ap2 NumDept Fnac 23/12/50 Fnac < 23/12/50 Fila seleccionada
1 Juan Prez Prez ... D01 ... 02/06/64 23/12/50 Falso
2 Pedro Lpez Blas ... D01 ... 23/12/50 23/12/50 Falso
3 Mara Prez Pi ... D02 ... 12/03/75 23/12/50 Falso
4 Antonio Botn Castro ... D02 ... 13/01/65 23/12/50 Falso
Como se puede apreciar, ninguna fila de la tabla satisface la condicin, por lo que el
resultado de la consulta ser una tabla vaca: Pedro es el empleado ms viejo de la
empresa!
NPila
Siempre que no sea posible determinar si una condicin se verifica para una
determinada fila, adoptaremos una postura conservadora: al ser desconocido el resultado
de la comparacin, descartaremos la fila al calcular el resultado de la condicin, por si
en un momento dado, y con ms informacin, llegsemos a determinar que la condicin
no se cumple.
Ejemplo: Recuperar el NSS de todos los empleados de la empresa que cuentan con un
supervisor.
Select NSS
FROM Empleado
WHERE NSSSupervisor > 0
Empleado
NSS Npila Ap1 Ap2 NSSSupervisor NSS NSSSupervisor NSSSupervisor Fila
>0? seleccionada
1 Juan Prez Prez ... ... 1 (Nulo) Desconocido
2 Pedro Lpez Blas ... 1 ... 2 1 Verdadero
3 Mara Prez Pi ... ... 3 (Nulo) Desconocido
4 Antonio Botn Castro ... 3 ... 4 3 Verdadero
Empleado
NSS Npila Ap1 Ap2 NSSSupervisor NSS NSS
2 Pedro Lpez Blas ... 1 ... 2 2
4 Antonio Botn Castro ... 3 ... 4 4
Select NSS
FROM Empleado
WHERE NSSSupervisor = NULL
devolvera como resultado una tabla vaca, por la propia semntica definida para la
clusula WHERE: el operador de comparacin = se evala a nulo si hay un nulo de por
medio, y en este caso todas las filas de la tabla original seran descartadas (en todas las
comparaciones intervendr el valor NULL).
Para resolver este contratiempo, SQL permite una alternativa en forma de predicado
lgico2: IS NULL. Este predicado (asociado a un nombre de columna) nos permitir
saber si el valor de dicha columna para una fila es nulo o no.
2
Podemos entender un predicado como una funcin que devuelve como resultado un valor lgico de
Verdadero o Falso
Select NSS
FROM Empleado
WHERE NSSSupervisor IS NULL
Y se evala de esta manera:
Empleado
NSS Npila Ap1 Ap2 NSSSupervisor NSS NSSSupervisor NSSSupervisor Fila
IS NULL ? seleccionada
1 Juan Prez Prez ... ... 1 (Nulo) Verdadero
2 Pedro Lpez Blas ... 1 ... 2 1 Falso
3 Mara Prez Pi ... ... 3 (Nulo) Verdadero
4 Antonio Botn Castro ... 3 ... 4 3 Falso
...siendo este el resultado final:
Empleado
NSS Npila Ap1 Ap2 NSSSupervisor NSS
1 Juan Prez Prez ... ... 1
3 Mara Prez Pi ... ... 3
El predicado IS NULL presenta adems una forma negada, que nos permite resolver de
forma ms elegante la consulta original (la lista de empleados con jefe):
Select NSS
FROM Empleado
WHERE NSSSupervisor IS NOT NULL
Empleado
NSS Npila Ap1 Ap2 NSSSupervisor NSS NSSSupervisor NSSSupervisor IS Fila
NOT NULL ? seleccionada
1 Juan Prez Prez ... ... 1 (Nulo) Falso
2 Pedro Lpez Blas ... 1 ... 2 1 Verdadero
3 Mara Prez Pi ... ... 3 (Nulo) Falso
4 Antonio Botn Castro ... 3 ... 4 3 Verdadero
Condiciones compuestas
Ejemplo: Recuperar los NSS de todos aquellos empleados del departamento de Ventas
que tienen jefe.
En esta consulta tenemos que seleccionar a los empleados a mostrar de acuerdo con dos
condiciones:
Select NSS
FROM Empleado
WHERE NumDept=D01
AND NSSSupervisor IS NOT NULL
Como se puede apreciar, se piden dos condiciones que deben cumplirse a la vez (de ah
que usemos la conectiva AND). La consulta se evala como sigue:
Empleado
Condicin2: Condicin1
Condicin1: Fila
NSS NumDept NSSSupervisor NSSSupervisor AND
NumDept=D01? Seleccionada
IS NOT NULL? Condicin2?
1 ... D01 Verdadero Falso Falso
2 ... D01 1 Verdadero Verdadero Verdadero
3 ... D02 Falso Falso Falso
4 ... D02 3 Falso Verdadero Falso
Como se ve, solo hay un empleado que cumpla las dos condiciones. El resultado de la
consulta sera este:
Ejemplo: Recuperar los NSS de todos aquellos empleados de la empresa que o bien
pertenezcan al departamento de Ventas o bien tengan jefe.
Select NSS
FROM Empleado
WHERE NumDept=D01
OR NSSSupervisor IS NOT NULL
Empleado
Condicin2: Condicin1
Condicin1: Fila
NSS NumDept NSSSupervisor NSSSupervisor OR
NumDept=D01? Seleccionada
IS NOT NULL? Condicin2?
1 ... D01 Verdadero Falso Verdadero
2 ... D01 1 Verdadero Verdadero Verdadero
3 ... D02 Falso Falso Falso
4 ... D02 3 Falso Verdadero Verdadero
Como se ve, solo hay un empleado que no cumple ninguna de las dos condiciones, y
que por lo tanto debe ser descartado. El resultado de la consulta sera este:
Se trata de una consulta ideal para el uso de NOT, ya que debemos establecer como
condicin que algo no se cumpla.
Empleado
Condicin1: Not (Condicin1): Fila
NSS NumDept
NumDept=D01? NOT (NumDept=D01)? Seleccionada
1 ... D01 Verdadero Falso
Empleado
NSS NumDept NSS
3 ... D02 3
4 ... D02 4
Es decir, seleccionamos a aquellos empleados cuyo jefe no tenga 1 por valor de NSS
(que es el de Juan).
Empleado
NOT(Condicin1):
Condicin1: Fila
NSS NSSSupervisor NOT ( NSSSupervisor
NSSSupervisor=1? Seleccionada
=1 ?
1 ... Desconocido Desconocido
2 ... 1 Verdadero Falso
3 ... Desconocido Desconocido
4 ... 3 Falso Verdadero
Select NSS
FROM Empleado
WHERE NOT(NSSSupervisor=1) OR NSSSupervisor IS NULL
3
De hecho, ninguno de los dos tiene jefe.
Es decir, sern incluidos en el resultado todos aquellos empleados que no tengan jefe
(NSSSupervisor IS NULL) o bien, si tienen jefe, su NSS no sea 1 (el de Juan)
Empleado
Condicin1: NOT(Condicin1): Condicin2:
NOT(Condicin1) Fila
NSS NSSSupervisor NSSSupervisor NOT (NSSSupervisor NSSSupervisor
OR Condicin 2? seleccionada
=1? =1) ? IS NULL?
1 ... Desconocido Desconocido Verdadero Verdadero
2 ... 1 Verdadero Falso Falso Falso
3 ... Desconocido Desconocido Verdadero Verdadero
4 ... 3 Falso Verdadero Falso Verdadero
Ahora s hemos conseguido descartar solamente a Pedro, que es el nico empleado que
tiene a Juan por jefe.
Empleado
NSS NSSSupervisor NSS
1 ... 1
3 ... 3
4 ... 3 4
Como hemos podido comprobar en este ejemplo, la presencia de valores nulos complica
siempre la realizacin de consultas. Se trata de uno de los motivos por los que como
ya ha sido sealado en alguna ocasin el diseo de las tablas de una BD debe ser
analizado detenidamente para evitar en lo posible la necesidad del uso de valores nulos.
Obtener los nombres de todos los empleados de la empresa, junto con el nombre de los
departamentos en los que trabajan.
La principal dificultad de escribir una consulta que obtenga esta informacin radica
precisamente en que la informacin est distribuida en dos tablas:
Sin embargo, ambas tablas incluyen una columna comn: NumDept. Esta columna, en
la tabla Empleado, nos permite representar/averiguar el nmero del departamento
correspondiente a cada empleado. A partir de ese nmero, podemos localizar la fila
correspondiente en la tabla Departamento y averiguar los datos del mismo.
Para resolver el problema, SQL nos permite especificar dos o ms tablas (separadas por
comas) en la clusula FROM; es decir, podemos especificar que queremos extraer la
informacin desde dos o ms tablas de la BD. Sin embargo, la evaluacin de la consulta
va a diferir ligeramente con respecto al mecanismo que habamos visto hasta ahora.
Dicho mecanismo de evaluacin constaba de los siguientes pasos:
Como se puede apreciar, los cambios (sealados en negrita) son mnimos: La esencia
del cambio radica en que vamos a obtener, de las tablas originales, una nueva tabla,
nica, sobre la que trabajar. Una vez obtenida esa tabla, podremos continuar
procediendo como habamos visto hasta ahora: evaluando las clusulas WHERE,
ORDER BY y SELECT sobre una nica tabla.
Empleado
NSS ... NumDept NSSSupervisor
1 ... D01 Departamento
2 ... D01 1 NumDept NomDept NSS FechaIniGerente
3 ... D02 D01 Ventas 1 01/01/2000
4 ... D02 3 D02 Produccion 3 01/01/2004
Tabla Combinada
NSS ... NumDept NSSSupervisor NumDept NomDept NSS FechaIniGerente
1 ... D01 D01 Ventas 1 01/01/2000
2 ... D01 1 D01 Ventas 1 01/01/2000
3 ... D02 D02 Produccion 2 01/01/2004
4 ... D02 3 D02 Produccion 2 01/01/2004
Como se puede apreciar, sera sencillo definir una consulta sobre la tabla combinada
para recuperar la informacin que se solicita en el ejemplo. Esa tabla combinada se
obtiene, en SQL, en dos pasos:
SELECT
FROM Empleado, Departamento
WHERE
Esas dos tablas sern combinadas, dando lugar a una tabla nica: cada fila de la
tabla Empleado ser combinada con todas y cada una de las filas de la tabla
Departamento, dando lugar a una nueva fila en la tabla combinada. Es decir, si
en la tabla Empleado tenemos 4 filas, y en la tabla Departamento tenemos 2
filas, la tabla combinada tendr un total de 4 x 2 = 8 filas.
Como se ve en la figura, en la tabla resultante del primer paso han sido incluidas
las siguientes combinaciones:
- La fila del empleado 1 (Juan) ha sido combinada con las filas de los
departamentos D01 y D02
- La fila del empleado 2 (Pedro) ha sido combinada con las filas de los
departamentos D01 y D02
- La fila del empleado 3 (Mara) ha sido combinada con las filas de los
departamentos D01 y D02
- La fila del empleado 4 (Antonio) ha sido combinada con las filas de
los departamentos D01 y D02
Para solucionar esta aparente ambigedad, lo que haremos ser utilizar prefijos
para designar a las columnas: cada nombre de columna, cuando la
referenciemos, ir precedida del nombre de la tabla de la que provenga,
separando ambos nombres por un punto (.) As, la consulta de reunin de nuestro
ejemplo pasa a ser...
SELECT
FROM Empleado, Departamento
WHERE Empleado.NumDept = Departamento.NumDept
Qu sucede cuando tenemos una clave fornea que referencia a una clave primaria de
la misma tabla? Que las cosas se complican!
Volvamos a nuestro ejemplo: la tabla Empleado contiene una clave fornea de ese tipo:
NSSSupervisor. Esta columna permite almacenar, para cada empleado, el NSS de su
jefe, que a su vez es un empleado y debe estar registrado en la tabla. Sin embargo, no se
incluye una columna para poder registrar el nombre del jefe da cada empleado entre el
resto de sus datos. Supongamos ahora que nos hacen llegar la siguiente peticin:
Para todos aquellos empleados de la empresa que tengan jefe, se necesita la lista de sus
nombres y los nombres de sus jefes inmediatos.
- Se recuperan los datos de todos los empleados con jefe de la empresa: todas
las filas de la tabla Empleado con NSSSupervisor no nulo.
- De cada fila, nos quedamos con el nombre del empleado (NPila) y el NSS de
su supervisor (NSSSupervisor).
- Utilizamos el NSS del supervisor, y localizamos la fila que le corresponde en
la tabla (de nuevo) Empleado.
- Recuperamos de la fila el nombre del supervisor (NPila)
Como se puede ver, estamos dando dos usos a la tabla Empleado; o, dicho de otra
manera, estamos contemplando la tabla desde dos puntos de vista:
Este hecho sugiere una posible va para la elaboracin de una consulta SQL que permita
obtener la informacin deseada: incluir dos veces la misma tabla (Empleado) en la
clusula FROM; y combinar las dos tablas de forma que cada fila de un empleado se
una a la fila correspondiente a su jefe. De ese modo, la tabla resultante tendr una fila
por cada empleado de la empresa, e incluir en cada una de ellas el nombre del
empleado, y el nombre de su jefe: precisamente, la informacin que necesitamos.
- Para poder diferenciar cada una de las copias, utilizaremos sendos alias de
la tabla: nombres (apodos) que le daremos a la tabla original cada vez que la
- Cada vez que debamos referirnos a una columna de alguna de las copias,
usaremos el alias como prefijo para indicar de cul de ellas. Si queremos
acceder a un dato sobre un empleado, usamos la copia Emp; y si queremos
referirnos a un dato sobre un jefe, usamos la copia Jefe.
- Para combinar los datos de cada empleado con los datos de su jefe,
establecemos la condicin de reunin siguiente: una fila de la copia Emp y
otra de la copia Jefe se unirn si la segunda representa al jefe del empleado
representado por la primera: es decir, si el NSS de la segunda (Jefe.NSS) es
igual al NSS del jefe indicado por la primera (Emp.NSSSupervisor).
Podemos verlo mejor acudiendo a los datos, y viendo cmo se combinan. Partimos de
dos copias idnticas de la tabla Empleado: Emp y Jefe
Emp Jefe
NSS NPila ... NSSSupervisor NSS NPila ... NSSSupervisor
1 Juan ... 1 Juan ...
2 Pedro ... 1 2 Pedro ... 1
3 Mara ... 3 Mara ...
4 Antonio ... 3 4 Antonio ... 3
Al evaluar la consulta, combinamos las dos copias, resultando la tabla siguiente:
Origen: Emp Origen: Jefe
NSS NPila ... NSSSupervisor NSS NPila ... NSSSupervisor
1 Juan ... 1 Juan ...
1 Juan ... 2 Pedro ... 1
1 Juan ... 3 Mara ...
1 Juan ... 4 Antonio ... 3
2 Pedro ... 1 1 Juan ...
2 Pedro ... 1 2 Pedro ... 1
2 Pedro ... 1 3 Mara ...
2 Pedro ... 1 4 Antonio ... 3
3 Mara ... 1 Juan ...
3 Mara ... 2 Pedro ... 1
3 Mara ... 3 Mara ...
3 Mara ... 4 Antonio ... 3
4 Antonio ... 3 1 Juan ...
4 Antonio ... 3 2 Pedro ... 1
4 Antonio ... 3 3 Mara ...
4 Antonio ... 3 4 Antonio ... 3
Nos quedamos, pues, con slo dos filas, sobre las que evaluamos las expresiones del
SELECT:
Vistas
Una vista, en SQL, es una consulta a la que se le asigna un nombre. De ese modo
podemos utilizar una consulta como si fuese una tabla, e incluirla incluso en otras
consultas. La utilidad principal de las vistas es proporcionar una manera de dar
diferentes visiones de la BD a los diferentes usuarios de la misma.4 Lo veremos con un
ejemplo: comprobaremos como mediante una vista podemos ampliar la tabla Empleado
permitiendo representar en ella un atributo derivado (la edad del empleado), calculada
con una funcin especial de SQL (datediff) que permite calcular la diferencia en aos
entre dos fechas dadas.5
La consulta que nos permite aadir esa columna a la tabla Empleado es esta:
NSS NPila Ap1 Ap2 Sexo Direccin FNac NumDept NSSSupervisor Edad
1 Juan Prez Prez H R/ Vilar 2 02/06/64 D01 40
2 Pedro Lpez Blas H R/ Fontes 12 23/12/50 D01 1 54
3 Mara Basco Pi M R/ Galicia 6 12/03/75 D02 29
4 Antonio Botn Castro H Pza Galicia 1 13/01/65 D02 3 39
4
Recordar el nivel externo de la arquitectura de la informacin, ya visto anteriormente.
5
Asumiremos que la funcin se comporta como debe, y no nos preocuparemos aqu de analizar su
funcionamiento en detalle.
Para convertir esta consulta en una vista, utilizamos la instruccin de SQL CREATE
VIEW, que presenta la siguiente sintaxis:
CREATE VIEW <Nombre vista> AS <Consulta Select>
En el caso de nuestro ejemplo:
SELECT *
FROM EmpleadoEdad
Bibliografa
- R. Elmasri y S. Navathe. Fundamentos de los Sistemas de Bases de Datos (3
edicin). Addison-Wesley, 2002.
- E. Rivero, L. Martnez, J. Benavides, L. Reina y J. Olaizola. Introduccin al SQL
para Usuarios y Programadores. Thomson, 2002.
- A. Silberschatz, H. F. Korth y S. Sudarshan. Fundamentos de Bases de Datos (4
edicin). McGraw Hill, 2002