Para la resolución de la mayoría de requerimientos es necesario trabajar con información que se obtiene de relacionar varias tablas. La forma de especificar qué tablas vamos a consultar es construir una lista de nombres de tablas en la cláusula from.
Si seleccionamos la BD Ejemplo, podemos preguntar por el
Nombre de los profesores y la descripción de las asignaturas que imparten
¿Dónde está la información solicitada? Consultando el esquema de la base de datos Ejemplo:
nombre (del profesor) se encuentra en la tabla PROFESORES y
descripción (de la asignatura) en ASIGNATURAS.
PROFESORES (
dni : varchar(10),
nombre : varchar(40),
categoria : char(4),
ingreso : date )
Clave primaria: dni
ASIGNATURAS (
codigo : char(5),
descripcion : varchar(35),
creditos : number(3,1),
creditosp : number(3,1) )
Clave primaria: codigo
IMPARTE (
dni : varchar(10),
asignatura :
char(5) )
Clave primaria: (dni, asignatura)
Clave ajena: dni → PROFESORES
Clave ajena: asignatura → ASIGNATURAS
Si no lo pensamos mucho podríamos ejecutar la siguiente orden confiando en el todopoderoso SGBD:
select nombre, descripcion
from asignaturas, profesores
Obviamente, el resultado anterior no se corresponde con la información solicitada, hemos hecho un producto cartesiano entre dos conjuntos, la combinación de todos los nombres de profesor con todas las descripciones de asignatura.
En este caso, la relación entre profesores y asignaturas se encuentra en imparte que tiene 2 claves ajenas, una está asociada a la clave primaria de profesor y la otra a la clave primaria de asignaturas. Pensemos en imparte como un "puente" que nos permite enlazar la información de la primera tabla con la segunda: de profesores pasamos a imparte mediante el dni, y de imparte a asignaturas mediante el código de la asignatura.
PROFESORES ← dni=dni → IMPARTE ← asignatura=codigo → ASIGNATURAS
Necesitamos, por tanto, incluir la tabla imparte en el from, y especificar en el where las condiciones para concatenar las tuplas deseadas.
Nombre de los profesores y descripción de las asignaturas que imparten
(lo que debemos mostar): select nombre, descripcion
(donde está la información necesaria): from asignaturas, profesores, imparte
(igualando claves ajenas y claves primarias): where imparte.dni = profesores.dni and asignatura = codigo
Para entender mejor cómo se obtienen los resultados de una consulta podemos pensar que el orden de ejecución es
from asignaturas, profesores, imparte (producto cartesiano)
where profesores.dni = imparte.dni and asignatura = codigo (selección)
select nombre, descripcion (proyección)
1.
select * from asignaturas, profesores, imparte
2.
select * from asignaturas, profesores, imparte
where profesores.dni = imparte.dni and asignatura = codigo
3.
select nombre, descripcion
from asignaturas, profesores, imparte where profesores.dni=imparte.dni and asignatura=codigo
Resumiendo, podemos decir que
from establece la fuente de datos,
where la información objetivo en bruto, y
select la extracción de la información deseada.
IMPORTANTE: Esto no es necesariamente real, una de las ventajas de utilizar un SGBD es que las consultas se procesan de manera eficiente y de forma totalmente transparente para el usuario. Es sólo una forma de comprender las acciones básicas que representa cada parámetro de la orden select.
Un nombre cualificado de atributo es el que especifica el nombre de la tabla a la que pertenece la columna:
profesores.dni
asignaturas.descripción
Es obligatorio utilizar nombres cualificados de atributo si hay ambigüedad, si varias tablas de la select tienen columnas que se llaman igual:
profesores.dni
imparte.dni
En cualquier otro caso no es necesario.
DNI y nombre de los profesores que imparten alguna asignatura
select profesores.dni, nombre
from profesores, imparte
where profesores.dni = imparte.dni
Es una orden correcta, sin ambigüedades. Pero si modificamos y no cualificamos el dni de la proyección:
select dni, nombre
from profesores, imparte
where profesores.dni = imparte.dni
Esto nos genera un error, la cualificación ha de hacerse en toda la orden debido a que SQL no sabe de qué tabla debe mostrar el dni.
Error at Command Line:3 Column:0
Error report:
SQL Error: Column 'dni' in field list is ambiguous
También es útil cuando, a partir de varias tablas, se quieren todas las columnas de una y sólo alguna de las otras
select profesores.*, descripcion
from profesores, asignaturas, imparte
where profesores.dni = imparte.dni
and codigo = asignatura
select * from tabla alias
Una cadena de caracteres a continuación del nombre de la tabla en el from, es un alias temporal, un nombre sustitutivo. Es recomendable para simplificar la escritura de la orden select o para hacerla más legible.
Es obligatorio para un producto cartesiano de una tabla por si misma:
select p1.nombre, p2.nombre
from profesores p1, profesores p2
where p1.nombre <> p2.nombre
Cuando se define el sinónimo en el from, sustituye totalmente al nombre de la tabla (no se permite utilizar los dos simultáneamente en el select o el where). Por otro lado, no es necesario definir sinónimos para todas las tablas del from.
DNI y nombre de los profesores que imparten alguna asignatura (utilizando sinónimos temporales de tabla)
select p.dni, nombre
from profesores p, imparte i
where p.dni = i.dni