El lenguaje SQL

Anuncio
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
El lenguaje SQL
El paso de la gestión automatizada de información basada en ficheros a la gestión
basada en el uso de Sistemas Gestores de Bases de Datos (SGBDs) trajo consigo
importantes cambios en el modo de diseñar, construir e utilizar aplicaciones
informáticas. Uno de los cambios más significativos fue la aparición de los
denominados lenguajes de consulta: muchos de los primeros SGBDs estaban
acompañados de uno o más lenguajes desarrollados específicamente para el acceso a la
información 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.
La auténtica diferencia de esos lenguajes con respecto a otros lenguajes de
programación es su carácter declarativo: en lugar de especificar paso a paso las
operaciones a realizar (la esencia de los lenguajes de programación imperativos), estos
lenguajes permiten especificar únicamente el resultado deseado; dejando al SGBD la
tarea de decidir la forma más adecuada de conseguir ese resultado. Esto convierte a los
lenguajes de consulta de BDs en auténticos lenguajes de alto nivel; y los hace
adecuados, por otro lado, para solucionar el problema de la dificultad de acceso a los
datos: necesidades de información inesperadas y puntuales pueden ser resueltas de
forma rápida y flexible.
Uno de los primeros lenguajes de consulta de BDs fue el Structured Query Language
(más conocido por sus siglas SQL), desarrollado por la compañía IBM para SYSTEM R,
un SGBD relacional experimental. Con el paso del tiempo, SQL se ha convertido en un
lenguaje estándar: prácticamente 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 versión más reciente del año 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
ejecución de una secuencia de operaciones del álgebra relacional (el álgebra – con los
correspondientes operadores - que el modelo relacional incluye para permitir la
manipulación de las relaciones).
Los SGBDs suelen incluir entre las herramientas que los acompañan un intérprete de
SQL: se trata de un programa informático capaz de recibir y evaluar consultas SQL,
conectándose con la BD adecuada, y presentando al usuario los resultados obtenidos. Y
los SGBDs también admiten que los programas de aplicación que necesiten acceder a
una determinada BD le envíen sus solicitudes de información en forma de consultas
SQL.
Aunque hablemos de lenguajes de consulta, SQL es un lenguaje completo: no sólo
permite recuperar información desde una BD, sino que también permite actualizar
dicha información, e incluso definir la estructura de la propia BD. Podemos decir que
SQL tiene dos vertientes:
Lenguaje de Manipulación de Datos (LMD): SQL incluye instrucciones para el
acceso y manipulación de la información contenida en una BD
Autor: Juan Ramón López Rodríguez
1
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
-
Instrucción SELECT: permite la recuperación de información
Instrucción INSERT: permite introducir nuevos datos en la BD
Instrucción UPDATE: permite la actualización de datos en la BD
Instrucción DELETE: permite la eliminación de información de
la BD
Lenguaje de Definición de Datos (LDD): SQL permite también la definición y
estructuración de las diferentes BDs controladas por un SGBD
- Instrucción CREATE TABLE: crea una nueva relación en la BD.
- Instrucción ALTER TABLE: permite la modificación de la
estructura de una relación ya existente en la BD.
- Instrucción DROP TABLE: permite la eliminación de una
relación en la BD.
Estas notas están destinadas a explicar únicamente la parte de SQL correspondiente a la
instrucción SELECT. En caso de estar interesado en el resto de instrucciones, el lector o
lectora puede acudir a la bibliografía citada en la última página, donde hayará
excelentes explicaciones y ejemplos.
Diferencias SQL – Modelo relacional
Si bien SQL está fuertemente ligado al modelo relacional, no es menos cierto que
presenta algunas diferencias importantes en cuanto al manejo de los datos:
-
-
-
Una primera diferencia es terminológica: donde el modelo relacional habla de
relaciones, tuplas, y atributos, SQL habla de tablas, filas y columnas. Nosotros no
haremos distinciones y manejaremos indistintamente ambas terminologías.
El modelo relacional no admite la existencia de tuplas repetidas en una relación
(restricción de clave). En cambio, SQL admite sin problemas la existencia de filas
repetidas en una tabla (veremos más adelante por qué).
Lo que en el modelo relacional son dominios (conjunto de valores válidos para un
atributo), en SQL son tipos de datos. Los tipos de datos definen los valores posibles
para un atributo, pero también las operaciones que pueden ser realizadas con esos
valores (suma, resta, multiplicación, división, concatenación....) . Los tipos de datos
más frecuentes en SQL son:
Tipo de datos SQL
NUMBER (numDigitos)
CHAR(numCaracteres)
DATETIME
Nombre que
recibe en Access
Númerico
TEXTO (numCaracteres)
Fecha/Hora
Operaciones soportadas
+,-,*,/
+ (concatenación)
Ejemplo
53
‘Casa’
03/09/57
Ejemplo a utilizar
Antes de abordar la descripción de la instrucción SELECT de SQL, estableceremos el
ejemplo de partida que utilizaremos a lo largo de la explicación. Se trata del esquema
lógico - relativo a la gestión de una empresa – que habíamos obtenido al analizar la
transformación desde el modelo ER al modelo relacional.
Autor: Juan Ramón López Rodríguez
2
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
Empleado (NSS, NPila, Ap1, Ap2, Sexo, Dirección, FNac, NumDept, NSSSupervisor)
Departamento (NumDept, NomDept, NSS, FechaIniGerente)
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:
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
Empleado
Ap1
Ap2 Sexo Dirección
Pérez Pérez
H
R/ Vilar 2
López Blas
H
R/ Fontes 12
Pérez
Pi
M
R/ Galicia 6
Botín Castro H Pza Galicia 1
FNac NumDept NSSSupervisor
02/06/64
D01
23/12/50
D01
1
12/03/75
D02
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 Coruña
D01
P1
Producto A
Ferrol
D02
P2
Producto B
Ferrol
D02
TrabajaEn
NSS Numero Horas
1
V1
10
2
V1
35
3
P1
20
4
P1
5
4
P2
30
LocalidadDpt
NumDept
Loc
D01
A Coruña
D02
A Coruña
D02
Ferrol
La instrucción SELECT
La instrucción SELECT de SQL se utiliza para recuperar (realizando un procesamiento
previo, si fuese necesario) información de la BD. Se trata de una instrucción que toma
como parámetros de entrada una o mas tablas, y devuelve como resultado una nueva
tabla, generada dinámicamente, que contiene la información 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 múltiples filas y columnas.
Autor: Juan Ramón López Rodríguez
3
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
La instrucción SELECT está formada por un conjunto de cláusulas, que ayudan a
precisar la información que se solicita. La sintaxis general de una instrucción SELECT
es la siguiente
SELECT [distinct] <lista de expresiones>
FROM <lista de tablas>
WHERE <condiciones de selección>
ORDER BY <lista expresiones ordenación>
-
cláusula select
cláusula from
cláusula where
cláusula order by
La cláusula FROM permite especificar la tabla o tablas de la base de datos desde
donde se va a recuperar la información que se necesita.
La cláusula WHERE permite especificar un conjunto de condiciones para la
selección de los datos que se recuperarán de las tablas para elaborar el resultado.
La cláusula SELECT permite especificar la información a recuperar exactamente, y,
de ser necesario, el procesamiento que debe ser realizado sobre esos datos.
Finalmente, la cláusula ORDER BY permite especificar el orden en el que va a ser
presentada la información en la tabla resultante.
En realidad, no todas estas cláusulas deben aparecer obligatorias en una consulta Select.
Sólo lás cláusulas SELECT y FROM son imprescindibles para formar una consulta
Select mínima.
La cláusula 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 sería la
siguiente:
Select NSS, NPila, Ap1, Ap2
FROM Empleado
...y el resultado de evaluar la consulta sería el siguiente:
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
Ap1
Ap2
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
¿Cómo se obtiene esta tabla? Una consulta Select se evalúa de la siguente manera:
1) En primer lugar, se evalúa la cláusula FROM: es necesario determinar de qué tabla
vamos a recuperar la información: por ejemplo, Empleado.
2) A continuación, se accede a la tabla indicada, y se recuperan, una a una, todas sus
filas, sobre las que será evaluada, una por una, la cláusula SELECT: cada fila de la
tabla original (Empleado) va a dar lugar a una nueva fila en la tabla que contendrá el
resultado de la consulta.
3) La cláusula SELECT debe contener una lista de una o más expresiones, separadas
Autor: Juan Ramón López Rodríguez
4
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
por comas.
- Cada una de esas expresiones será evaluada sobre cada fila de la tabla
original, dando lugar a una lista de valores atómicos (tantos como
expresiones)
- La lista obtenida servirá para crear una nueva fila en la tabla resultado.
- La tabla resultado tendrá una columna por cada expresión incluida en la
cláusula SELECT
- El nombre de cada columna será igual a la expresión que la genera.
4) Serán expresiones válidas (expresiones que pueden ser utilizadas en la cláusula
SELECT):
- Un valor constante, de cualquiera de los tipos de datos admitidos en SQL:
por ejemplo ‘Juan’, 5, 03/02/2004. El resultado de evaluar un valor
constante sobre una fila coincide siempre con el propio valor constante.
- Un nombre de columna de aquellos incluidos en la tabla indicada en el
FROM: por ejemplo, NSS, NPila, Ap1 o Ap2. Al evaluar un nombre de
columna sobre una fila determinada, el resultado será el valor de la fila en
esa columna.
- Una expresión que incluya operaciones realizadas sobre valores constantes
y/o nombres de columnas. El resultado de la expresión será el mismo que el
resultado de evaluar primero los valores constantes y los nombres de
columnas, y operarlos después. Por ejemplo:





2 (Resultado: 2)
2+3 (Resultado: 5)
‘Fede’ + ‘rico’ (Resultado: ‘Federico’)
Ap1 + Ap2 (Resultado: dada una fila de la tabla original, la
concatenación de los valores de sus columnas Ap1 y Ap2)
‘Nombre:’ + NPila (Resultado: dada una fila de la tabla original, la
concatenación de la cadena ‘Nombre:’ y el valor de la fila en la
columna NPila)
En el caso de nuestro ejemplo, la evaluación de la consulta se realiza como sigue:
-
-
En primer lugar, se utiliza la cláusula FROM para determinar la tabla de origen
de los datos: Empleado, que es la tabla que contiene toda la información que
necesitamos.
A continuación, se analiza una por una cada fila de Empleado:
Para la primera fila...
NSS NPila Ap1 Ap2 Sexo Dirección FNac NumDept NSSSupervisor
1
Juan Pérez Pérez H
R/ Vilar 2 02/06/64
D01
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 1
NPila: ‘Juan’
Ap1: ‘Pérez’
Ap2: ‘Pérez’
...y por lo tanto, la fila que se genera en la tabla resultado es:
1 Juan Pérez Pérez
Autor: Juan Ramón López Rodríguez
5
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Para la segunda fila...
NSS NPila Ap1 Ap2 Sexo Dirección
FNac NumDept NSSSupervisor
2 Pedro López Blas H R/ Fontes 12 23/12/50
D01
1
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 2
NPila: ‘Pedro’
Ap1: ‘López’
Ap2: ‘Blas’
...y por lo tanto, la fila que se añade a la tabla resultado es:
2 Pedro López Blas
Para la tercera fila...
NSS NPila Ap1 Ap2 Sexo Dirección
FNac NumDept NSSSupervisor
3 María Pérez Pi
M R/ Galicia 6 12/03/75
D02
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 3
NPila: ‘María’
Ap1: ‘Pérez’
Ap2: ‘Pi’
...y por lo tanto, la fila que se añade a la tabla resultado es:
3 María Pérez Pi
Finalmente, para la cuarta y última fila...
NSS NPila Ap1 Ap2 Sexo Dirección
FNac NumDept NSSSupervisor
4 Antonio Botín Castro H Pza Galicia 1 13/01/65
D02
3
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 4
NPila: ‘Antonio’
Ap1: ‘Botín’
Ap2: ‘Castro’
...y por lo tanto, la fila que se añade a la tabla resultado es:
4 Antonio Botín Castro
-
Como último paso, las filas obtenidas se unen para obtener la tabla
resultante:
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
-
Ap1
Ap2
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
Como se puede apreciar, las columnas tienen por nombre la expresión
(incluida en la cláusula SELECT) que da lugar a sus valores
La consulta que hemos visto utiliza expresiones en la cláusula SELECT que están
constituidas por simples nombres de columnas. Sin embargo, podemos realizar
consultas más sofisticadas incluyendo expresiones más complejas. Por ejemplo,
podemos modificar la consulta anterior para que el nombre completo de cada empleado
aparezca en una única columna:
Autor: Juan Ramón López Rodríguez
6
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Select NSS, Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila
FROM Empleado
En esta nueva consulta, reemplazamos las tres expresiones que se referían a las
columnas de nombre y apellidos de los empleados por una expresión única, en la que se
utiliza el operador de concatenación de cadenas (+) para unir los valores de dichas
columnas, separados por espacios y comas: se trata de una expresión en la que se
combinan nombres de atributos y valores constantes (‘ ‘ y ‘,’ ). La consulta se evaluará
de la siguiente forma:
Para la primera fila...
NSS NPila Ap1 Ap2 Sexo Dirección FNac NumDept NSSSupervisor
1
Juan Pérez Pérez H
R/ Vilar 2 02/06/64
D01
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 1
Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila = ‘Pérez’ + ‘ ‘ + ‘Pérez’ + ‘, ‘ + ‘Juan’ = ‘Pérez Pérez, Juan’
...y por lo tanto, la fila que se genera en la tabla resultado es:
1 Pérez Pérez, Juan
Para la segunda fila...
NSS NPila Ap1 Ap2 Sexo Dirección
FNac NumDept NSSSupervisor
2 Pedro López Blas H R/ Fontes 12 23/12/50
D01
1
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 2
Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila = ‘López’ + ‘ ‘ + ‘Blas’ + ‘, ‘ + ‘Pedro’ = ‘López Blas, Pedro’
...y por lo tanto, la fila que se añade a la tabla resultado es:
2 López Blas, Pedro
Para la tercera fila...
NSS NPila Ap1 Ap2 Sexo Dirección
FNac NumDept NSSSupervisor
3 María Pérez Pi
M R/ Galicia 6 12/03/75
D02
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 3
Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila = ‘Pérez’ + ‘ ‘ + ‘Pi’ + ‘, ‘ + ‘María’ = ‘Pérez Pi, María’
...y por lo tanto, la fila que se añade a la tabla resultado es:
3 Pérez Pi, María
Finalmente, para la cuarta y última fila...
NSS NPila Ap1 Ap2 Sexo Dirección
FNac NumDept NSSSupervisor
4 Antonio Botín Castro H Pza Galicia 1 13/01/65
D02
3
...las expresiones de la cláusula SELECT se evalúan así:
NSS: 4
Autor: Juan Ramón López Rodríguez
7
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila = ‘Botín’ + ‘ ‘ + ‘Castro’ + ‘, ‘ + ‘Antonio’ = ‘Botín Castro, Antonio’
...y por lo tanto, la fila que se añade a la tabla resultado es:
4 Botín Castro, Antonio
-
Como último paso, las filas obtenidas se unen para obtener la tabla
resultante:
NSS Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila
1
Pérez Pérez, Juan
2
López Blas, Pedro
3
Pérez Pi, María
4
Botín Castro, Antonio
Las expresiones complejas no tienen por que utilizar sólo atributos o valores de tipo
carácter. La siguiente consulta devuelve el número mensual de horas que cada empleado
le dedica a cada proyecto (que se obtienen multiplicando por 4 el número de horas
semanal por proyecto, almacenado en la tabla TrabajaEn):
Select NSS, Numero, Horas* 4
FROM TrabajaEn
Es fácil comprobar que el resultado de esta consulta sería la siguiente tabla:
TrabajaEn
NSS Numero Horas*4
1
V1
40
2
V1
140
3
P1
80
4
P1
20
4
P2
120
Con este ejemplo demostramos algo que habíamos afirmado anteriormente: la
instrucción Select de SQL permite no sólo recuperar información almacenada en una
BD, sino también procesar dicha información para generar información nueva.
Valores nulos
El modelo relacional admite el uso de los valores nulos durante la asignación de
valores a los atributos de una tupla. Eso significa, en la terminología de SQL, que
podemos encontrarnos con celdas de una tabla que alberguen valores nulos.
Por lo tanto, la cláusula SELECT puede involucrar, en sus expresiones, valores nulos (al
evaluar esas expresiones sobre los valores de una fila determinada). La pregunta es
¿cómo afectan los valores nulos al cálculo de expresiones incluidas en una cláusula
SELECT? Y la respuesta es sencilla: el valor de un nulo es desconocido; por lo tanto, en
toda expresión en la que intervenga un valor nulo, el resultado será también
desconocido.1 Y en la tabla resultante, el valor desconocido se representará mediante
otro valor nulo.
-
1
2 + Nulo = Nulo
‘Casa’ + Nulo = Nulo
NSS – 5 = Nulo (si NSS se evalúa a Nulo)
Ya que, si nos falta alguno de los parámetros de la expresión, es imposible determinar el resultado.
Autor: Juan Ramón López Rodríguez
8
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Ejemplo: Indica el NSS de cada empleado y el de su jefe.
Select NSS, NSSSupervisor
FROM Empleado
La consulta se evalúa de la siguiente forma:
NSS Npila
1
Juan
2
Pedro
3
María
4
Antonio
Empleado
Ap1
Ap2 …
Pérez Pérez ...
López Blas ...
Pérez
Pi
...
Botín Castro ...
NSSSupervisor
1
3
…
...
...
...
...
NSS
1
2
3
4
NSSSupervisor
(Nulo)
1
(Nulo)
3
NSS
1
2
3
4
NSSSupervisor
1
3
Filas repetidas: el modificador distinct
Supongamos que necesitamos conocer las diferentes localidades en las que nuestra
empresa dispone de alguna sede. En la base de datos contamos con información
referente a las sedes de los departamentos de la empresa (concretamente, en la tabla
LocalidadDpt); y conociendo las sedes de los departamentos, conoceremos las de la
empresa (ya que, en buena lógica, deben coincidir). Por lo tanto, la siguiente consulta
debería servir a nuestros fines:
SELECT Loc
FROM LocalidadDpt
Como en los casos anteriores, la consulta se evalúa recuperando una por una las filas de
la tabla indicada y evaluando las expresiones de la cláusula SELECT sobre cada una de
ellas:
LocalidadDpt
NumDept
Loc
D01
A Coruña
D02
A Coruña
D02
Ferrol
Evaluación de ‘Loc’:
A Coruña
A Coruña
Ferrol
El resultado de la consulta sería este:
Loc
A Coruña
A Coruña
Ferrol
Como se puede apreciar, una de las localidades aparece repetida: se trata de A Coruña,
como resultado de ser obtenida como sede de dos departamentos diferentes. Esto es así
porque SQL incumple la restricción de clave del modelo relacional, que exige que en
una relación (una tabla) no puede haber filas repetidas. Así, al verse liberado de la
obligación de comprobar esta restricción, cualquier intérprete de SQL podrá procesar
una consulta mucho más rápidamente.
Sin embargo, SQL sí que permite eliminar filas repetidas en el resultado de una consulta
(aunque provocando, probablemente, un retraso adicional por parte del intérprete en la
Autor: Juan Ramón López Rodríguez
9
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
obtención del resultado final). Para hacerlo, la cláusula SELECT cuenta con el
modificador distinct: añadiendo este modificador a nuestra consulta...
SELECT distinct Loc
FROM LocalidadDpt
...el resultado de la misma pasaría a ser este:
Loc
A Coruña
Ferrol
...de forma que obtendríamos ya los datos en la forma deseada.
Es importante resaltar que distinct permite eliminar filas repetidas, y no valores
repetidos. Por ejemplo, estas dos consultas (que nos devuelven una lista con los
nombres de los empleados y el departamento en el que trabajan):
SELECT NumDept, Npila
FROM Empleado
SELECT distinct NumDept, Npila
FROM Empleado
…devolverán como resultado la misma tabla:
NumDept NPila
D01
Juan
D01
Pedro
D02
María
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.
Versión abreviada del SELECT
Es bastante usual encontrarse en la necesidad de recuperar toda la información
contenida en una tabla. Hacerlo por medio de una consulta SQL implicaría escribir uno
por uno todos los nombres de sus columnas en la cláusula SELECT:
SELECT NSS, Npila, Ap1, Ap2, Sexo, Direccion, Fnac, NumDept, NSSSupervisor
FROM Empleado
Para evitar esto, la cláusula SELECT admite un carácter comodín, que representa a
todas las columnas de una tabla: el asterisco (*). Así, la siguiente consulta sería
equivalente a la anterior:
SELECT *
FROM Empleado
Ordenación del resultado: la cláusula ORDER BY.
En los ejemplos anteriores estamos asumiendo que el orden de presentación de los
resultados de una consulta se basa en el orden inicial de las filas de la tabla de partida.
Autor: Juan Ramón López Rodríguez
10
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
En realidad, nada nos garantiza ese orden: la definición formal de SQL no nos indica
nada a ese respecto. Además, la definición del modelo relacional (que, no lo olvidemos,
es la base de SQL) especifica que una relación (una tabla) es un conjunto de tuplas:
tratándose de un conjunto, el concepto de orden no es aplicable. ¿A dónde 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.
En realidad, se trata de un problema que tiene fácil solución: SQL incorpora, en la
instrucción SELECT, una cláusula – ORDER BY – que nos permite especificar el orden
deseado de presentación de los resultados.
El orden se establece a través de una o más expresiones de ordenación, que se
incluyen en la cláusula ORDER BY separadas por comas:
-
-
-
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 ordenación: en primer lugar se tienen en cuenta los
resultados de la primera expresión; se toman después en cuenta los
resultados de la segunda; y así sucesivamente.
Los valores resultantes de cada expresión pueden ser ordenados de forma
ascendente o descendente: para ello se utilizan los modificadores ASC (la
opción por defecto) y DESC.
Las filas del resultado se ordenan en función del orden establecido para las
filas de la tabla original a partir de las que son obtenidas.
Veremos a continuación dos ejemplos del uso de la cláusula ORDER BY para precisar
mejor su funcionamiento.
Ejemplo: Obtener la lista de empleados de la empresa, ordenados alfabéticamente por
sus apellidos.
SELECT NSS, Ap1+ ‘ ‘ + Ap2 + ‘,’ + Npila
FROM Empleado
ORDER BY Ap1, Ap2, Nombre
Esta consulta se evalúa de la siguiente forma:
-
Para cada fila de la tabla Empleado se evalúan las expresiones de ordenación:
Empleado
NSS NPila Ap1
Ap2
1
Juan Pérez Pérez
2
Pedro López Blas
3
María Pérez
Pi
4 Antonio Botín Castro
-
…
...
...
...
...
Ap1
Ap2
NPila
Pérez Pérez Juan
López Blas Pedro
Pérez
Pi
María
Botín Castro Antonio
Las filas se ordenan empleando la primera expresión (Ap1), de forma ascendente (la
opción por defecto):
Empleado
NSS NPila Ap1
Ap2 …
4 Antonio Botín Castro ...
2
Pedro López Blas ...
Autor: Juan Ramón López Rodríguez
Ap1
Ap2
NPila
Botín Castro Antonio
López Blas Pedro
11
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
3
1
-
María
Juan
Pérez
Pi
Pérez Pérez
...
...
María
Juan
Como se puede observar, dos filas (las correspondientes a María y Pedro) presentan
en mismo valor para Ap1. Para decidir su orden, recurrimos a la segunda expresión
(Ap2)
Empleado
NSS NPila Ap1
Ap2
4 Antonio Botín Castro
2
Pedro López Blas
1
Juan Pérez Pérez
3
María Pérez
Pi
-
Pérez
Pi
Pérez Pérez
…
...
...
...
...
Ap1
Ap2
NPila
Botín Castro Antonio
López Blas Pedro
Pérez Pérez Juan
Pérez
Pi
María
Ya no es necesario recurrir a la última expresión (NPila) para resolver el orden final.
Conocido el orden, llega el momento de evaluar la cláusula SELECT y resolver la
consulta, respetando el orden previamente establecido.
Empleado
NSS NPila Ap1
Ap2
4 Antonio Botín Castro
2
Pedro López Blas
1
Juan Pérez Pérez
3
María Pérez
Pi
…
...
...
...
...
NSS
4
2
1
3
Ap1+ ‘ ‘ + Ap2 + ‘,’ + Npila
Botín Castro, Antonio
López Blas, Pedro
Pérez Pérez, Juan
Pérez Pi, María
Ejemplo: Indicar los NSS de todos los empleados de la empresa, ordenados por
departamento y por edad (los más jóvenes 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 sería esta:
SELECT NSS, NumDept
FROM Empleado
ORDER BY NumDept, Fnac DESC
Obsérvese 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)
El resultado de la consulta sería el siguiente:
Empleado
NSS Npila Ap1
1
Juan Pérez
2
Pedro López
3
María Pérez
4 Antonio Botín
Ap2
Pérez
Blas
Pi
Castro
…
...
...
...
...
NumDept
D01
D01
D02
D02
FNac
02/06/64
23/12/50
12/03/75
13/01/65
NSS NumDept
1
D01
2
D01
3
D02
4
D02
(Se da la casualidad en el ejemplo que el orden solicitado en origen para las tuplas es
aquel en el que las habíamos presentado inicialmente).
Filtrado de información: la cláusula WHERE
La cláusula WHERE permite afinar en mayor medida la recuperación de información
mediante una instrucción SELECT. Hasta ahora hemos visto cómo seleccionar cuáles de
Autor: Juan Ramón López Rodríguez
12
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
las columnas de una tabla nos interesan; mediante WHERE podremos seleccionar
cuáles 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.
Select NSS, Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila
FROM Empleado
WHERE NumDept=’D01’
Para seleccionar las filas que nos interesen, la cláusula WHERE va acompañada de un
conjunto de condiciones de selección. Sólo las filas que cumplan esas condiciones
serán tenidas en cuenta para evaluar la consulta.
Condiciones simples
La condición de selección más sencilla que se puede definir es aquella que obliga a
comparar los valores de dos expresiones evaluadas sobre cada fila de la tabla.
Expresión1
=
>
<
<>
>=
<=
Expresión 2
La idea es que tanto Expresión1 como Expresión2 se evalúen sobre los valores de cada
fila de la tabla original. Una vez evaluados, se comparan. Si la condición especificada se
cumple, la fila se selecciona. Si la condición 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 evaluación se haría así:
-
En primer lugar, seleccionar las filas a utilizar para calcular el resultado, aplicando
la condición de selección del WHERE
NSS Npila
1
Juan
2
Pedro
3
María
4 Antonio
-
Empleado
Ap1
Ap2
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
… NumDept …
...
D01
...
...
D01
...
...
D02
...
...
D02
...
NumDept
D01
D01
D02
D02
‘D01’
D01
D01
D01
D01
NumDept=’D01’
Verdadero
Verdadero
Falso
Falso
Fila seleccionada




Una vez seleccionadas las filas, se procede de la forma acostumbrada:
Empleado
NSS Npila Ap1 Ap2 … NumDept …
1
Juan Pérez Pérez ...
D01
...
2 Pedro López Blas ...
D01
...
Autor: Juan Ramón López Rodríguez
NSS Ap1 + ‘ ‘ + Ap2 + ‘, ‘ + NPila
1
Pérez Pérez, Juan
2
López Blas, Pedro
13
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
Otro ejemplo podría ser este: Nombres de todos los empleados de la empresa que hayan
nacido antes que Pedro.
La consulta que nos permite obtener esa información es esta:
Select NPila
FROM Empleado
WHERE Fnac<23/12/50
Y se evaluará de la siguiente forma:
NSS Npila
1
Juan
2
Pedro
3
María
4 Antonio
Empleado
Ap1
Ap2
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
… NumDept …
...
D01
...
...
D01
...
...
D02
...
...
D02
...
Fnac
02/06/64
23/12/50
12/03/75
13/01/65
23/12/50
23/12/50
23/12/50
23/12/50
23/12/50
Fnac < 23/12/50
Falso
Falso
Falso
Falso
Fila seleccionada




Como se puede apreciar, ninguna fila de la tabla satisface la condición, por lo que el
resultado de la consulta será una tabla vacía: ¡Pedro es el empleado más viejo de la
empresa!
NPila
Valores nulos: el predicado IS NULL
Los valores nulos también afectan a la evaluación de las condiciones de selección. La
evaluación de cualquier condición de selección en la que intervenga una expresión con
evaluación desconocida, será también desconocida.
-
-
¿ 2 > Nulo ?
Desconocido
¿ ‘Casa’ <> Nulo ? Desconocido
¿ NSS = 5 ? Desconocido (si NSS se evalúa a Nulo)
Siempre que no sea posible determinar si una condición se verifica para una
determinada fila, adoptaremos una postura conservadora: al ser desconocido el resultado
de la comparación, descartaremos la fila al calcular el resultado de la condición, por si
en un momento dado, y con más información, llegásemos a determinar que la condición
no se cumple.
Ejemplo: Recuperar el NSS de todos los empleados de la empresa que cuentan con un
supervisor.
La consulta que nos permite obtener esta información es la siguiente:
Select NSS
FROM Empleado
WHERE NSSSupervisor > 0
…y se evalúa de la siguiente forma:
Autor: Juan Ramón López Rodríguez
14
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
NSS
Npila
1
2
3
4
Juan
Pedro
María
Antonio
Empleado
Ap1
Ap2 … NSSSupervisor …
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
...
...
...
...
1
3
...
...
...
...
NSS NSSSupervisor
1
2
3
4
(Nulo)
1
(Nulo)
3
¿ NSSSupervisor
>0?
Desconocido
Verdadero
Desconocido
Verdadero
Fila
seleccionada




Como se puede apreciar, dos filas – correspondientes a dos empleados de la empresa –
presentan un valor nulo en la columna NSSSupervisor. En esos dos casos, la condición
¿NSSSupervisor > 0 ? no puede ser evaluada, y las dos filas se descartan. Es decir,
estamos descartando las filas correspondientes a empleados sin supervisor; que es
precisamente lo que pretendíamos hacer.
La consulta se termina de evaluar de la siguiente forma:
NSS Npila
2
Pedro
4
Antonio
Empleado
Ap1
Ap2 …
López Blas ...
Botín Castro ...
NSSSupervisor
1
3
…
...
...
NSS
2
4
NSS
2
4
El siguiente ejemplo resulta más complicado de resolver:
Ejemplo: Recuperar el NSS de todos los empleados de la empresa que no tienen
supervisor.
Se trata de seleccionar aquellas filas (empleados) con valor nulo en la columna
NSSSupervisor. El problema es el siguiente: cualquier comparación con un valor nulo
hará que una fila sea descartada, precisamente lo contrario de lo que deseamos en este
caso. Por ejemplo, es fácil ver cómo la siguiente consulta...
Select NSS
FROM Empleado
WHERE NSSSupervisor = NULL
… devolvería como resultado una tabla vacía, por la propia semántica definida para la
cláusula WHERE: el operador de comparación = se evalúa a nulo si hay un nulo de por
medio, y en este caso todas las filas de la tabla original serían descartadas (en todas las
comparaciones intervendrá el valor NULL).
Para resolver este contratiempo, SQL permite una alternativa en forma de predicado
lógico2: 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.
-
Si el valor de la columna es nulo, IS NULL se evaluará como Verdadero
Si el valor de la columna no es nulo, IS NULL se evaluará como Falso
Utilizando IS NULL en nuestro ejemplo, la consulta se resuelve así:
2
Podemos entender un predicado como una función que devuelve como resultado un valor lógico de
Verdadero o Falso
Autor: Juan Ramón López Rodríguez
15
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
Select NSS
FROM Empleado
WHERE NSSSupervisor IS NULL
Y se evalúa de esta manera:
NSS
Npila
1
2
3
4
Juan
Pedro
María
Antonio
Empleado
Ap1
Ap2 … NSSSupervisor …
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
...
...
...
...
1
3
...
...
...
...
NSS NSSSupervisor
1
2
3
4
(Nulo)
1
(Nulo)
3
¿ NSSSupervisor
IS NULL ?
Verdadero
Falso
Verdadero
Falso
Fila
seleccionada




...siendo este el resultado final:
Empleado
NSS Npila Ap1 Ap2 … NSSSupervisor …
1
Juan Pérez Pérez ...
...
3 María Pérez
Pi
...
...
NSS
1
3
El predicado IS NULL presenta además una forma negada, que nos permite resolver de
forma más elegante la consulta original (la lista de empleados con jefe):
Select NSS
FROM Empleado
WHERE NSSSupervisor IS NOT NULL
Esta consulta se evalúa de esta manera:
NSS
Npila
1
2
3
4
Juan
Pedro
María
Antonio
Empleado
Ap1
Ap2 … NSSSupervisor …
Pérez Pérez
López Blas
Pérez
Pi
Botín Castro
...
...
...
...
1
3
...
...
...
...
NSS NSSSupervisor ¿ NSSSupervisor IS
Fila
NOT NULL ?
seleccionada
1
(Nulo)
Falso

2
1
Verdadero

3
(Nulo)
Falso

4
3
Verdadero

...siendo ahora este el resultado final:
Empleado
NSS Npila Ap1
Ap2 … NSSSupervisor …
2
Pedro López Blas ...
1
...
4 Antonio Botín Castro ...
3
...
NSS
2
4
...ya que el predicado IS NOT NULL, asociado a un nombre de columna, presenta la
siguiente evaluación:
-
Si el valor de la columna es nulo, IS NOT NULL se evaluará como Falso
Si el valor de la columna no es nulo, IS NOT NULL se evaluará como
Verdadero
Condiciones compuestas
Autor: Juan Ramón López Rodríguez
16
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
La cláusula WHERE permite especificar condiciones más complejas de consulta, por
medio de las conectivas lógicas: AND , OR y NOT. Las conectivas lógicas permiten
combinar dos o mas condiciones (simples o compuestas), de la siguiente forma:
condición1
Verdadero
Verdadero
Falso
Verdadero
Falso
Desconocido
condición2
Verdadero
Falso
Falso
Desconocido
Desconocido
Desconocido
condicion1 AND condición2
Verdadero
Falso
Falso
Desconocido
Falso
Desconocido
condición1
Verdadero
Falso
Desconocido
NOT (condición1)
Falso
Verdadero
Desconocido
condicion1 OR condición2
Verdadero
Verdadero
Falso
Verdadero
Desconocido
Desconocido
La mejor forma de entender la forma de especificar una condición de selección
compuesta es con un ejemplo. Supongamos que pretendemos realizar la siguiente
consulta:
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:
-
Por un lado, los empleados deben pertenecer al departamento de Ventas
(D01)
Por otro lado, los empleados deben tener un supervisor (un jefe)
-
Se trata claramente de una condición compuesta. La consulta que proporciona esta
información es esta:
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 evalúa como sigue:
Empleado
NSS … NumDept NSSSupervisor
1
2
3
4
...
...
...
...
D01
D01
D02
D02
1
3
Condición2: ¿Condición1
Condición1:
Fila
¿NSSSupervisor
AND
¿NumDept=’D01’?
Seleccionada
IS NOT NULL? Condición2?
Verdadero
Falso
Falso

Verdadero
Verdadero
Verdadero

Falso
Falso
Falso

Falso
Verdadero
Falso

Como se ve, solo hay un empleado que cumpla las dos condiciones. El resultado de la
consulta sería este:
Autor: Juan Ramón López Rodríguez
17
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
NSS … NumDept NSSSupervisor
2
...
D01
1
NSS
2
Supongamos ahora que la información solicitada es la siguiente:
Ejemplo: Recuperar los NSS de todos aquellos empleados de la empresa que o bien
pertenezcan al departamento de Ventas o bien tengan jefe.
En este caso, las condiciones indicadas varían ligeramente: ya no se trata de dos
condiciones que deban cumplirse juntas; ahora nos interesan los empleados que
cumplan una cualquiera de ellas. Por lo tanto, la conectiva a utilizar es, en este caso,
OR:
Select NSS
FROM Empleado
WHERE NumDept=’D01’
OR NSSSupervisor IS NOT NULL
Esta nueva consulta se evalúa como sigue:
Empleado
NSS … NumDept NSSSupervisor
1
2
3
4
...
...
...
...
D01
D01
D02
D02
1
3
Condición2: ¿Condición1
Condición1:
Fila
¿NSSSupervisor
OR
¿NumDept=’D01’?
Seleccionada
IS NOT NULL? Condición2?
Verdadero
Falso
Verdadero

Verdadero
Verdadero
Verdadero

Falso
Falso
Falso

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 sería este:
NSS
1
2
4
… NumDept NSSSupervisor
...
D01
...
D01
1
...
D02
3
NSS
1
2
4
Otro ejemplo podría ser este:
Seleccionar a aquellos empleados que no trabajen en el departamento de Ventas.
Se trata de una consulta ideal para el uso de NOT, ya que debemos establecer como
condición que algo no se cumpla.
Select distinct NSS
FROM Empleado
WHERE NOT(NumDept=’D01’)
Empleado
NSS … NumDept
1
...
D01
Autor: Juan Ramón López Rodríguez
Condición1:
Not (Condición1):
Fila
¿NumDept=’D01’? ¿NOT (NumDept=’D01’)? Seleccionada
Verdadero
Falso

18
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
2
3
4
...
...
...
D01
D02
D02
Verdadero
Falso
Falso
Falso
Verdadero
Verdadero



Como se puede ver, seleccionamos exclusivamente a aquellos empleados que no
pertenecen a Ventas.
Empleado
NSS … NumDept
3
...
D02
4
...
D02
NSS
3
4
Analizaremos un último ejemplo, algo más complejo de lo que podría parecer en un
principio:
Seleccionar a los empleados cuyo jefe no es Juan.
Aparentemente, esta consulta se resuelve fácilmente utilizando de nuevo el predicado
NOT:
Select NSS
FROM Empleado
WHERE NOT(NSSSupervisor=1)
Es decir, seleccionamos a aquellos empleados cuyo jefe no tenga 1 por valor de NSS
(que es el de Juan).
Empleado
NSS … NSSSupervisor
1
2
3
4
...
...
...
...
1
3
NOT(Condición1):
Condición1:
Fila
¿NOT ( NSSSupervisor
¿NSSSupervisor=1?
Seleccionada
=1 ?
Desconocido
Desconocido

Verdadero
Falso

Desconocido
Desconocido

Falso
Verdadero

Como se puede apreciar, estamos descartando las filas correspondientes a dos
empleados (Juan y María) ¡que no tienen a Juan como jefe! 3; y que por lo tanto
deberían aparecer en el resultado de la consulta.
La culpa de que no aparezcan es de los valores nulos. Efectivamente, ni Juan ni María
tienen jefe, por lo que NSSSupervisor toma para ambos el valor Nulo. Al comparar
NSSSupervisor con 1 (el NSS de Juan), el resultado es desconocido, por lo que ambas
filas resultan descartadas.
Se impone por lo tanto una modificación de la consulta, para tratar convenientemente
todos aquellos casos en los que NSSSupervisor sea Nulo. La forma de hacerlo es esta:
Select NSS
FROM Empleado
WHERE NOT(NSSSupervisor=1) OR NSSSupervisor IS NULL
3
De hecho, ninguno de los dos tiene jefe.
Autor: Juan Ramón López Rodríguez
19
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
Es decir, serán 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
NSS … NSSSupervisor
1
2
3
4
...
...
...
...
1
3
Condición1:
NOT(Condición1):
Condición2:
¿NOT(Condición1)
Fila
¿NSSSupervisor ¿NOT (NSSSupervisor ¿NSSSupervisor
OR Condición 2? seleccionada
=1?
=1) ?
IS NULL?
Desconocido
Desconocido
Verdadero
Verdadero

Verdadero
Falso
Falso
Falso

Desconocido
Desconocido
Verdadero
Verdadero

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
…
1
...
3
...
4
...
NSSSupervisor
3
NSS
1
3
4
Como hemos podido comprobar en este ejemplo, la presencia de valores nulos complica
siempre la realización de consultas. Se trata de uno de los motivos por los que – como
ya ha sido señalado en alguna ocasión – el diseño de las tablas de una BD debe ser
analizado detenidamente para evitar en lo posible la necesidad del uso de valores nulos.
Consultas sobre varias tablas
Hasta ahora, todos los ejemplos que hemos visto se referían a consultas que permitían
recuperar la información contenida en una única tabla. Sin embargo, en muchas
ocasiones va a ser necesario combinar los datos almacenados en varias tablas para poder
obtener la información que se necesite. Supongamos por ejemplo esta petición de
información:
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 información radica
precisamente en que la información está distribuida en dos tablas:
-
El nombre de los empleados se encuentra en la tabla Empleado
El nombre de los departamentos se encuentra en la tabla Departamento
Sin embargo, ambas tablas incluyen una columna común: NumDept. Esta columna, en
la tabla Empleado, nos permite representar/averiguar el número del departamento
correspondiente a cada empleado. A partir de ese número, 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 más tablas (separadas por
comas) en la cláusula FROM; es decir, podemos especificar que queremos extraer la
información desde dos o más tablas de la BD. Sin embargo, la evaluación de la consulta
va a diferir ligeramente con respecto al mecanismo que habíamos visto hasta ahora.
Dicho mecanismo de evaluación constaba de los siguientes pasos:
Autor: Juan Ramón López Rodríguez
20
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
1. Determinar la tabla de origen, indicada en la cláusula FROM
2. Seleccionar aquellas filas que cumplen la condición o condiciones
especificadas en la cláusula WHERE
3. Ordenar las filas de la tabla original de acuerdo con lo especificado en la
cláusula ORDER BY
4. A partir de cada fila de la tabla original, generar una fila en la tabla
resultante, a partir de la evaluación de las expresiones indicadas en la
cláusula SELECT
El mecanismo a seguir en el caso de consultas definidas sobre varias tablas va a ser
ahora:
1. Determinar las tablas de origen, indicadas en la cláusula FROM
2. Combinar las tablas originales, de forma que se genere una tabla única
sobre la que trabajar.
3. Seleccionar aquellas filas de la tabla original que cumplen la condición o
condiciones especificadas en la cláusula WHERE
4. Ordenar las filas de la tabla original de acuerdo con lo especificado en la
cláusula ORDER BY
5. A partir de cada fila de la tabla original, generar una fila en la tabla
resultante, a partir de la evaluación de las expresiones indicadas en la
cláusula SELECT
Como se puede apreciar, los cambios (señalados en negrita) son mínimos: 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 habíamos visto hasta ahora: evaluando las cláusulas WHERE,
ORDER BY y SELECT sobre una única tabla.
Evidentemente, la clave del correcto funcionamiento de la consulta está en la forma en
la que se realizará la combinación de las (dos o mas) tablas originales. La idea es
combinar las filas de una tabla con las filas que tenga asociadas en el resto de tablas. En
el caso de nuestro ejemplo, deberíamos intentar combinar cada fila correspondiente a un
empleado con la fila correspondiente a su departamento. De esta forma, en la tabla
combinada seguiríamos contando con una fila por cada empleado, que incluiría además
toda la información relativa a su departamento.
Autor: Juan Ramón López Rodríguez
21
Grao en Información e Documentación: Bases de datos documentais
NSS
1
2
3
4
Empleado
... NumDept NSSSupervisor
...
D01
...
D01
1
...
D02
...
D02
3
NSS
1
2
3
4
Curso 2013 – 2014
Departamento
NumDept NomDept NSS FechaIniGerente
D01
Ventas
1
01/01/2000
D02
Produccion 3
01/01/2004
Tabla Combinada
... NumDept NSSSupervisor NumDept NomDept NSS FechaIniGerente
...
D01
D01
Ventas
1
01/01/2000
...
D01
1
D01
Ventas
1
01/01/2000
...
D02
D02
Produccion 2
01/01/2004
...
D02
3
D02
Produccion 2
01/01/2004
Como se puede apreciar, sería sencillo definir una consulta sobre la tabla combinada
para recuperar la información que se solicita en el ejemplo. Esa tabla combinada se
obtiene, en SQL, en dos pasos:
1. En primer lugar, se realiza el producto cartesiano de los conjuntos de filas de
todas las tablas. Es decir, se establecen todas las combinaciones posibles de cada
fila de una tabla con las filas de todas las demás tablas, ¡tengan o no sentido!
En el caso de la consulta de nuestro ejemplo, sabemos ya que la cláusula FROM
contendrá dos tablas: Empleado y Departamento.
SELECT
FROM Empleado, Departamento
WHERE
Esas dos tablas serán 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.
Tabla Combinada: Paso 1
NSS
1
1
2
2
3
3
4
4
Origen: Tabla Empleado
Origen: Tabla Departamento
... NumDept NSSSupervisor NumDept NomDept NSS FechaIniGerente
...
D01
D01
Ventas
1
01/01/2000
...
D01
D02
Produccion 2
01/01/2004
...
D01
1
D01
Ventas
1
01/01/2000
...
D01
1
D02
Produccion 2
01/01/2004
...
D02
D01
Ventas
1
01/01/2000
...
D02
D02
Produccion 2
01/01/2004
...
D02
3
D01
Ventas
1
01/01/2000
...
D02
3
D02
Produccion 2
01/01/2004
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
Autor: Juan Ramón López Rodríguez
22
Grao en Información e Documentación: Bases de datos documentais
-
Curso 2013 – 2014
La fila del empleado 2 (Pedro) ha sido combinada con las filas de los
departamentos D01 y D02
La fila del empleado 3 (María) 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
...resultando un total de 8 filas, tal y como habíamos calculado
2. No todas la combinaciones realizadas tienen interés para nosotros. Atendiendo a
la consulta que queremos realizar, sólo son relevantes aquellas en las que los
datos de un empleado han sido combinados con los datos del departamento en el
que trabaja. El segundo paso consiste en seleccionar aquellas combinaciones de
interés, por medio del establecimiento de una o más condiciones de reunión:
las condiciones que hacen válida una combinación de filas de diferentes tablas.
¿Cómo se especifican las condiciones de reunión? Aprovechando un mecanismo
ya conocido: la cláusula WHERE. Ampliaremos las condiciones de esta cláusula
incluyendo aquellas que convierten en válidas a las filas de la tabla combinada.
En el caso de nuestro ejemplo, para nosotros serán válidas aquellas
combinaciones de filas de empleado y departamento para las que el valor de
NumDepto coincida. Esa será pues, la condición de reunión a establecer en la
cláusula WHERE.
SELECT
FROM Empleado, Departamento
WHERE NumDept = NumDept
Un problema de combinar varias tablas es que la tabla combinada puede acabar
incluyendo varias columnas con el mismo nombre. Nuestro ejemplo no podía ser
menos y existen varias columnas en esa situación en la tabla combinada: NSS,
procedente de la tabla Empleado (representa el NSS de cada empleado) y NSS,
procedente de la tabla Departamento (que representa el NSS del director del
departamento); NumDept, procedente de la tabla Empleado (que representa el
número de departamento de cada empleado de la empresa), y NumDept,
procedente de la tabla Departamento (que representa en número de cada
departamento de la empresa). ¿Cómo distinguirlas cuando nos refiramos a ellas?
(por ejemplo, en la condición de reunión NumDept = NumDept)
Para solucionar esta aparente ambigüedad, 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 reunión de nuestro
ejemplo pasa a ser...
SELECT
FROM Empleado, Departamento
WHERE Empleado.NumDept = Departamento.NumDept
…y de este modo resolvemos cualquier posible ambigüedad en cuanto a las
columnas a las que nos referimos en la condición. Podemos así seleccionar las
filas que son coherentes:
Autor: Juan Ramón López Rodríguez
23
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
Tabla Combinada: Paso 2
Origen: Tabla Empleado Origen: Tabla Departamento
NSS ... NumDept … NumDept NomDept …
1 ...
D01
…
D01
Ventas
...
1 ...
D01
…
D02
Produccion ...
2 ...
D01
…
D01
Ventas
...
2 ...
D01
…
D02
Produccion ...
3 ...
D02
…
D01
Ventas
...
3 ...
D02
…
D02
Produccion ...
4 ...
D02
…
D01
Ventas
...
4 ...
D02
…
D02
Produccion ...
Empleado.NumDept =
Departamento.NumDept
Verdadero
Falso
Verdadero
Falso
Falso
Verdadero
Falso
Verdadero
Fila seleccionada








Resultando la tabla combinada final:
Tabla Combinada después del paso 2
Origen: Tabla Empleado
NSS NPila ... NumDept
1
Juan ...
D01
2
Pedro ...
D01
3
María ...
D02
4 Antonio ...
D02
Origen: Tabla Departamento
... NumDept NomDept …
...
D01
Ventas
...
...
D01
Ventas
...
...
D02
Produccion ...
...
D02
Produccion ...
Una vez obtenida la tabla combinada definitiva, es posible ya comprobar el resto de
condiciones especificadas en la cláusula WHERE, evaluar las expresiones de la cláusula
SELECT y calcular el resultado final
SELECT Npila, NomDept
FROM Empleado, Departamento
WHERE Empleado.NumDept = Departamento.NumDept
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
Tabla Combinada después del paso 2
... NumDept ... NumDept NomDept
...
D01
...
D01
Ventas
...
D01
...
D01
Ventas
...
D02
...
D02
Produccion
...
D02
...
D02
Produccion
…
...
...
...
...
Resultado consulta
NPila NomDept
Juan
Ventas
Pedro
Ventas
María Produccion
Antonio Produccion
Es necesario observar que, de pretender incluir en el resultado el número del
departamento, deberíamos especificar de cuál de las dos columnas con el mismo
nombre de la tabla combinada pretenderíamos extraerlo. Las posibilidades serían dos: la
columna procedente de Empleado, o la columna procedente de Departamento.
Cualquiera de las dos opciones sería válida
SELECT Npila, Empleado.NumDept, NomDept
FROM Empleado, Departamento
WHERE Empleado.NumDept = Departamento.NumDept
SELECT Npila, Departamento.NumDept, NomDept
FROM Empleado, Departamento
WHERE Empleado.NumDept = Departamento.NumDept
Consultas que involucran varias veces a la misma tabla.
Autor: Juan Ramón López Rodríguez
24
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
¿Qué sucede cuando tenemos una clave foránea 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 foránea 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 petición:
Para todos aquellos empleados de la empresa que tengan jefe, se necesita la lista de sus
nombres y los nombres de sus jefes inmediatos.
Es fácil pensar cómo obtener manualmente la información:
-
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:
1. Tabla que mantiene información sobre los empleados de la empresa.
2. Tabla que mantiene información sobre los jefes de la empresa.
O lo que es lo mismo: estamos combinando una tabla ¡consigo misma!
Este hecho sugiere una posible vía para la elaboración de una consulta SQL que permita
obtener la información deseada: incluir dos veces la misma tabla (Empleado) en la
cláusula 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 información que necesitamos.
La consulta a realizar sería esta:
SELECT Emp.Npila, Jefe.NPila
FROM Empleado Emp, Empleado Jefe
WHERE Emp.NSSSupervisor = Jefe.NSS
Para poder entender la consulta, debemos aclarar una serie de cuestiones:
-
Incluir dos veces a Empleado la misma tabla en la cláusula FROM nos da la
ilusión de contar con dos copias exactamente iguales de la tabla: una con
información sobre empleados y otra con información sobre jefes.
-
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
Autor: Juan Ramón López Rodríguez
25
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
incluyamos en la cláusula FROM, y que utilizaremos en todo el resto de la
consulta para referirnos a cada una de las “copias” resultantes.
En el ejemplo, usamos el alias Emp para referirnos a la tabla Empleado en su
papel de contenedora de información sobre los empleados; y el alias Jefe
para referirnos a Empleado en su papel de contenedora de información sobre
los jefes - supervisores - de empleados.
-
Cada vez que debamos referirnos a una columna de alguna de las “copias”,
usaremos el alias como prefijo para indicar de cuál 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 condición de reunión siguiente: una fila de la “copia” Emp y
otra de la “copia” Jefe se unirán 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 cómo se combinan. Partimos de
dos “copias” idénticas de la tabla Empleado: Emp y Jefe
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
Emp
... NSSSupervisor
...
...
1
...
...
3
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
Jefe
... NSSSupervisor
...
...
1
...
...
3
Al evaluar la consulta, combinamos las dos “copias”, resultando la tabla siguiente:
NSS
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4
Origen: Emp
Origen: Jefe
NPila ... NSSSupervisor NSS NPila ... NSSSupervisor
Juan ...
1
Juan ...
Juan ...
2
Pedro ...
1
Juan ...
3
María ...
Juan ...
4 Antonio ...
3
Pedro ...
1
1
Juan ...
Pedro ...
1
2
Pedro ...
1
Pedro ...
1
3
María ...
Pedro ...
1
4 Antonio ...
3
María ...
1
Juan ...
María ...
2
Pedro ...
1
María ...
3
María ...
María ...
4 Antonio ...
3
Antonio ...
3
1
Juan ...
Antonio ...
3
2
Pedro ...
1
Antonio ...
3
3
María ...
Antonio ...
3
4 Antonio ...
3
Y al evaluar la condición de reunión, el resultado será este otro:
Origen: Emp
Origen: Jefe
NSS
NPila
... NSSSupervisor NSS
NPila
... NSSSupervisor
1
1
Juan
Juan
...
...
Juan
Pedro
...
...
1
2
Autor: Juan Ramón López Rodríguez
1
¿Emp.NSSSupervisor
Fila
= Jefe.NSS?
Seleccionada
Desconocido
Desconocido
26
Curso 2013 – 2014
Grao en Información e Documentación: Bases de datos documentais
1
1
2
2
2
2
3
3
3
3
4
4
4
4
Juan
Juan
Pedro
Pedro
Pedro
Pedro
María
María
María
María
Antonio
Antonio
Antonio
Antonio
...
...
...
...
...
...
...
...
...
...
...
...
...
...
3
4
1
2
3
4
1
2
3
4
1
2
3
4
1
1
1
1
3
3
3
3
María
Antonio
Juan
Pedro
María
Antonio
Juan
Pedro
María
Antonio
Juan
Pedro
María
Antonio
...
...
...
...
...
...
...
...
...
...
...
...
...
...
3
1
3
1
3
1
3
Desconocido
Desconocido
Verdadero
Falso
Falso
Falso
Desconocido
Desconocido
Desconocido
Desconocido
Falso
Falso
Verdadero
Falso


Nos quedamos, pues, con sólo dos filas, sobre las que evaluamos las expresiones del
SELECT:
Origen: Emp
Origen: Jefe
NSS NPila ... NSSSupervisor NSS NPila ... NSSSupervisor
2
Pedro ...
1
1
Juan ...
4 Antonio ...
3
3 María ...
Emp.NPila Jefe.NPila
Pedro
Juan
Antonio
María
Y conseguimos así la información que necesitábamos, con una consulta de lo más
sencilla.
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 función especial de SQL (datediff) que permite calcular la diferencia en años
entre dos fechas dadas. 5
La consulta que nos permite añadir esa columna a la tabla Empleado es esta:
SELECT *, DateDiff("yyyy", FNac,Now()) AS Edad
FROM Empleado
...con el siguiente resultado:
NSS NPila
1
Juan
2
Pedro
3
María
4 Antonio
Ap1
Ap2 Sexo Dirección
Pérez Pérez
H
R/ Vilar 2
López Blas
H
R/ Fontes 12
Basco
Pi
M
R/ Galicia 6
Botín Castro H Pza Galicia 1
FNac NumDept NSSSupervisor Edad
02/06/64
D01
40
23/12/50
D01
1
54
12/03/75
D02
29
13/01/65
D02
3
39
4
Recordar el nivel externo de la arquitectura de la información, ya visto anteriormente.
Asumiremos que la función se comporta como debe, y no nos preocuparemos aquí de analizar su
funcionamiento en detalle.
5
Autor: Juan Ramón López Rodríguez
27
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Para convertir esta consulta en una vista, utilizamos la instrucción de SQL CREATE
VIEW, que presenta la siguiente sintaxis:
CREATE VIEW <Nombre vista> AS <Consulta Select>
En el caso de nuestro ejemplo:
CREATE VIEW EmpleadoEdad AS
SELECT *, DateDiff("yyyy", FNac,Now()) AS Edad
FROM Empleado
Una vez definida la vista, ya podrá ser utilizada en cualquier consulta:
SELECT *
FROM EmpleadoEdad
NOTA: Access no soporta la definición de vistas. En su lugar, todas las consultas
creadas en Access se convierten implícitamente en una vista.
Autor: Juan Ramón López Rodríguez
28
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Apéndice: Mecanismo de evaluación de las consultas
SELECT
Se reproduce a continuación, de forma separada para comodidad del lector/a, la
secuencia de evaluación de una sentencia SELECT:
1. Determinar las tablas de origen, indicadas en la cláusula FROM
2. Combinar las tablas originales, de forma que se genere una tabla única sobre
la que trabajar.
3. Seleccionar aquellas filas de la tabla original que cumplen la condición o
condiciones especificadas en la cláusula WHERE
4. Ordenar las filas de la tabla original de acuerdo con lo especificado en la
cláusula ORDER BY
5. A partir de cada fila de la tabla original, generar una fila en la tabla
resultante, a partir de la evaluación de las expresiones indicadas en la
cláusula SELECT
Autor: Juan Ramón López Rodríguez
29
Grao en Información e Documentación: Bases de datos documentais
Curso 2013 – 2014
Bibliografía
-
R. Elmasri y S. Navathe. Fundamentos de los Sistemas de Bases de Datos (3ª
edición). Addison-Wesley, 2002.
E. Rivero, L. Martínez, J. Benavides, L. Reina y J. Olaizola. Introducción al SQL
para Usuarios y Programadores. Thomson, 2002.
A. Silberschatz, H. F. Korth y S. Sudarshan. Fundamentos de Bases de Datos (4ª
edición). McGraw Hill, 2002
Autor: Juan Ramón López Rodríguez
30
Descargar