Consultas A Una Tabla: Introducción

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 47

TEMA

4
CONSULTAS A UNA TABLA

Introducción
En este capítulo aprenderá el comando SQL SELECT que se usa para recuperar datos en una
base de datos. Examinará los modos de organizar datos y usar las funciones de SQL para consultar
filas y calcular totales. También aprenderá los comandos SELECT anidados situando un comando
SELECT dentro de otro. Por último, aprenderá como agrupar filas que contienen valores iguales en
alguna columna.

Construir consultas sencillas


Una de las características más importantes de un DBMS es la posibilidad que ofrece de
contestar un amplio rango de preguntas con relación a los datos de una base de datos. Cuando
necesitamos encontrar datos para responder a una pregunta específica, utilizamos una consulta.
Una consulta es una pregunta representada de manera que el DBMS pueda comprender.

En SQL utilizamos el comando SELECT para consultar una base de datos. La forma básica del
comando SELECT es SELECT-FROM-WHERE. Después de la palabra SELECT, listamos las columnas
que queremos incluir en los resultados de la consulta. Esta parte del comando se denomina
cláusula SELECT. Después, escribimos la palabra FROM seguida del nombre de la tabla que
contiene los datos que queremos consultar. Esta parte del comando se denomina cláusula FROM.
Por último, después de la palabra WHERE, listamos las condiciones (restricciones) que se apliquen
a los datos que queremos recuperar. Esta parte opcional del comando se denomina cláusula
WHERE. Por ejemplo, cuando tenemos que recuperar las filas de sólo los clientes con límite de
crédito $7500.00, incluimos una condición en la cláusula WHERE especificando que el valor de la
columna limiCreClien ha de ser $7500.00 (limiCreClien=7500). No hay reglas especiales de
formato en SQL. En este libro, las cláusulas FROM y WHERE (cuando se utiliza) aparecen en líneas
separadas sólo para que los comandos sean más legibles y comprensibles.
Asignatura: Sistemas de Base de Datos

Recuperar determinadas columnas y todas las filas


Podemos escribir un comando para recuperar las columnas especificadas y todas las filas de
una tabla, como vemos en el ejemplo 1.

Ejemplo 1:
Liste el código, nombre y balance de todos los clientes.

Como tenemos que listar todos los clientes, no tenemos que incluir ninguna cláusula WHERE,
pues no necesitamos especificar restricción alguna a los datos que queremos recuperar.
Simplemente listaremos las columnas que queremos incluir (codiClien, nombreClien y balanClien)
en la cláusula SELECT y el nombre de la tabla (tCliente) en la cláusula FROM. Escriba un punto y
coma para indicar el final del comando y después haga clic en el botón Ejecutar para mostrar los
resultados. La consulta y sus resultados aparecen en la figura 4.1.

Nota: En Oracle Database Express Edition, el número que aparece en el cuadro Mostrar indica el
número máximo de filas que mostrará Oracle en los resultados de la consulta. El valor por defecto
el 10. Para cambiarlo, puede hacer clic en la flecha y seleccionar un nuevo valor de la lista o
escribirlo en el cuadro. En la figura 4.1 vemos el cuadro de lista Mostrar con el valor cambiado por
el usuario para mostrar 100 filas. Cuando ejecutamos una consulta cuyos resultados incluirán más
filas que el número del cuadro de lista Mostrar, Oracle lo indicará con un mensaje. Si ocurre esta
situación, aumente el número del cuadro de lista Mostrar y después haga clic de nuevo en el
botón Ejecutar para mostrar todos los resultados de la consulta. Si utilizamos SQL Server para
ejecutar los comandos SQL de este libro, los resultados de nuestras consultas pueden diferir
ligeramente de los que vemos en las figuras. En SQL Server, los valores del campo balanClien
tendrán dos posiciones decimales y los valores del campo fechaPedi se pueden mostrar con un
valor de tiempo. Aunque nuestros resultados pueden tener un formato diferente, los datos
deberían ser los mismos que vemos en las figuras.

select codiClien,nombreClien,balanClien from tCliente;

Figura 4.1. Comando SELECT para seleccionar determinadas columnas de la tabla tCliente.

Recuperar todas las columnas y todas las filas

31
Asignatura: Sistemas de Base de Datos

Podemos utilizar el mismo tipo de comando ilustrado en el ejemplo 1 para recuperar todas las
columnas y todas las filas de una tabla. Sin embargo, como vemos en el ejemplo 2, podemos
utilizar un método abreviado para llevar a cabo esta tarea.

Ejemplo 2
Liste la tabla tArticulo completa

En lugar de incluir todas las columnas en la cláusula SELECT, podemos utilizar un asterisco (*) para
indicar que queremos incluir todas las columnas. El resultado listará todas las columnas en el
orden en que se las describimos al DBMS al crear la tabla. Si quiere que las columnas aparezcan
en otro orden, escriba los nombres de las columnas en el orden en que quiere que aparezcan en
los resultados de la consulta. En este caso, asumiendo que el orden por defecto es adecuado,
podemos utilizar la consulta que vemos en la figura 4.2 para mostrar toda la tabla tArticulo.

select * from tArticulo;

Figura 4.2. Comando SELECT para seleccionar todas las columnas de la tabla tArticulo.

Cláusula WHERE
Cuando tenemos que recuperar filas que cumplan alguna condición, incluiremos la cláusula
WHERE en el comando SELECT, como vemos en el ejemplo 3.

Ejemplo 3
¿Cómo se llama el cliente con el código de cliente 148?

Podemos utilizar la cláusula WHERE para restringir los resultados de la consulta al código de
cliente 148, como vemos en la figura 4.3. Como codiClien es una columna de caracteres, el valor
148 irá entre comillas simples. Además, como la columna codiClien es la clave principal de la tabla
tCliente, sólo puede haber un cliente cuyo número coincida con el número especificado en la
cláusula WHERE.

31
Asignatura: Sistemas de Base de Datos

select nombreClien from tCliente where codiClien=148;

Figura 4.3. Comando SELECT para encontrar el nombre del cliente con código 148.

La condición de la cláusula WHERE que hemos visto se llama condición simple. Una condición
simple tiene la forma de un nombre de columna, un operador de comparación y después otro
nombre de columna o bien un valor. En la tabla 4.1 se recogen los operadores de comparación
que se pueden utilizar en SQL. Observe que hay dos versiones del operador “no igual a”: < > y !=.

Operador de comparación Descripción


= Igual a
< Menor que
> Mayor que
<= Menor que o igual a
>= Mayor que o igual a
<> No igual a
!= No igual a
Tabla 4.1. Operadores de comparación utilizados en comandos SQL.

Ejemplo 4
Encuentre el código y nombre de los clientes situados en la ciudad de Grove.

La única diferencia entre este ejemplo y el anterior es que en el ejemplo 3, no podía haber más de
una fila en la respuesta porque la condición implicaba a la clave principal de la tabla. En el
ejemplo 4 la condición implica a una columna que no es la clave principal de la tabla. Como hay
más de un cliente situado en la ciudad de Grove, los resultados pueden y de hecho contienen más
de una fila, como vemos en la figura 4.4.

select codiClien,nombreClien from tCliente where ciudadClien='grove';

Figura 4.4. Comando SELECT para encontrar a todos los clientes situados en Grove.

Ejemplo 5
Encuentre el código, nombre, balance y límite de crédito para todos los clientes con balances que
excedan sus límites de crédito.

31
Asignatura: Sistemas de Base de Datos

Una condición sencilla también puede comparar los valores almacenados en dos columnas. En la
figura 4.5 la cláusula WHERE incluye un operador de comparación que selecciona sólo las filas en
las que el balance es mayor que el límite de crédito.

select codiClien,nombreClien,balanClien,limiCreClien from tCliente


where balanClien>limiCreClien;

Figura 4.5. Comando SELECT para encontrar a todos los clientes con balances que exceden sus
límites de crédito.

Condiciones compuestas
Las condiciones que hemos visto hasta ahora se denominan condicionales simples. Los siguientes
ejemplos requieren condiciones compuestas. Una condición compuesta se forma conectando dos
o más condiciones simples con los operadores AND, OR y NOT. Cuando el operador AND conecta
condiciones simples, todas las condiciones simples deben ser verdaderas para que la condición
compuesta sea verdadera. Cuando el operador OR conecta las condiciones simples, la condición
compuesta será verdadera siempre que cualquier otra de las condiciones simples lo sea. Preceder
una condición del operador NOT invierte la verdad de la condición original. Por ejemplo, si la
condición original es verdadera, la condición nueva será falsa, y si la condición original es falsa, la
nueva será verdadera.

Ejemplo 6
Liste las descripciones de todos los artículos situados en el almacén 3 Y para las que haya más de
25 unidades.

En el ejemplo 6 se trata de recuperar aquellos artículos que cumplan ambas condiciones: el


número de almacén es igual a 3 y el número de unidades es mayor que 25. Para encontrar la
respuesta, formamos una condición compuesta utilizando el operador AND, como vemos en la
figura 4.6. La consulta examina los datos de la tabla tArticulo y lista los artículos situados en el
almacén 3 y para las que hay más de 25 unidades. Cuando una cláusula WHERE utiliza el operador
AND para conectar condiciones simples, también se le denomina una condición AND.

select descripArti from tArticulo where almaArti=3 and stockArti>25;

Figura 4.6. Comando SELECT con una condición AND en líneas separadas.

31
Asignatura: Sistemas de Base de Datos

Para que sea más legible, cada una de las condiciones simples de la consulta que vemos en la
figura 4.6 aparece en una línea separada. Hay usuarios que prefieren poner las condiciones en la
misma línea con cada una de las condiciones simples entre paréntesis, como vemos en la figura
4.7. Ambos métodos llevan a cabo la misma función. En este libro las condiciones simples
aparecen en líneas aparte y sin paréntesis.

select descripArti from tArticulo where almaArti=3 and stockArti>25;

Figura 4.7. Comando SELECT con una condición AND en la misma línea.

Ejemplo 7
Liste las descripciones de todos los artículos situados en el almacén 3 O en las que haya más de 25
unidades.

En el ejemplo 7, se trata de recuperar las descripciones para aquello artículos para las que el
número de almacén sea igual a 3, o para las que el número de unidades sea mayor que 25, o
ambos. Para ello, formaremos una condición compuesta utilizando el operador OR, como vemos
en la figura 4.8. Cuando una cláusula WHERE utiliza el operador OR para conectar condiciones
simples, también se denomina una condición OR.

select descripArti from tArticulo where almaArti=3 or stockArti>25;

Figura 4.8. Comando SELECT con una condición OR.

Ejemplo 8
Liste las descripciones de todos los artículos que NO están en el almacén 3.

Para el ejemplo 8, podríamos utilizar una condición simple y el operador “no igual a” (WHERE
almaArti <> ‘3’). Como alternativa, podemos utilizar el operador igual (=) en la condición y

31
Asignatura: Sistemas de Base de Datos

preceder toda la condición del operador NOT, como vemos en la figura 4.9. Cuando una cláusula
WHERE utiliza el operador NOT para conectar condiciones simples, también se denomina una
condición NOT.

select descripArti from tArticulo where almaArti<>3;

Figura 4.9. Comando SELECT con una condición NOT.

No es necesario que la condición almaArti=’3’ vaya entre paréntesis, pero de esta manera el
comando es más legible.

Operador BETWEEN
El ejemplo 9 requiere una condición compuesta para determinar la respuesta.

Ejemplo 9
Liste el código, nombre y balance de todos los clientes con balances mayores o iguales a $2000 y
menores o iguales a $5000.

Para recuperar los datos, podemos utilizar una cláusula WHERE y el operador AND, como vemos
en la figura 4.10.

Nota: En SQL los números incluidos en las consultas se introducen sin símbolos adicionales, como
pueden ser el símbolo del dólar o las comas.

Una alternativa a este método sería utilizar el operador BETWEEN, como vemos en la figura 4.11.
El operador BETWEEN nos permite especificar un rango de valores en una condición.

select codiClien, nombreClien,balanClien from tCliente


where balanClien>=2000 and balanClien<=5000;

Figura 4.10. Comando SELECT con una condición AND para una sola columna.

31
Asignatura: Sistemas de Base de Datos

select codiClien, nombreClien,balanClien from tCliente


where balanClien between 2000 and 5000

Figura 4.11. Comando SELECT con el operador BETWEEN.

El operador BETWEEN es inclusivo, lo que significa que la consulta selecciona un valor igual a
cualquier valor de la condición y en el rango de los valores. Por ejemplo, en la cláusula BETWEEN
2000 AND 5000 los valores entre 2000 y 5000 harían la condición verdadera. Podemos utilizar el
operador BETWEEN en Oracle y SQL Server.

El operador BETWEEN no es una función esencial en SQL, ya hemos visto que podemos obtener el
mismo resultado sin él. Sin embargo, la utilización del operador BETWEEN hace que determinados
comandos SELECT sean más sencillos de contruir.

Columnas de Cálculo
Con las consultas de SQL podemos llevar a cabo diferentes cálculos. La columna de cálculo no
existe en la base de datos pero se puede calcular utilizando datos de las columnas existentes. Los
cálculos pueden llevar cualquiera de los operadores aritméticos que vemos en la tabla 4.2.

Operador aritmético Descripción


+ Suma
- Resta
* Multiplicación
/ División
Tabla 4.2. Operadores aritméticos.

Ejemplo 10
Encuentre el código, nombre y crédito disponible (el límite de crédito menos el balance) de cada
cliente.

31
Asignatura: Sistemas de Base de Datos

Figura 4.12. Comando SELECT con una columna de cálculo.

En la base de datos de Premiere Products no existe ninguna columna que almacene el crédito
disponible de los clientes, pero podemos calcularlo utilizando las columnas limiCreClien y
balanClien. Para calcular el crédito disponible, utilizaremos la expresión limiCreClien – balanClien,
como vemos en la figura 4.12.

Los paréntesis antes y después del cálculo (limiCreClien – balanClien) no son esenciales pero lo
hacen más legible. También se pueden asignar un nombre a una columna de cálculo poniendo
delante del cálculo la palabra AS y el nombre deseado. Por ejemplo, el comando que vemos en la
figura 4.13 asigna el nombre crediDisClien a la columnas de cálculo.
select codiClien,nombreClien,(limiCreClien-balanClien)as crediDisClien
from tCliente;

Figura 4.13. Comando SELECT con una columna de cálculo nombrada.

Ejemplo 11
Encuentre el código, nombre y crédito disponible de los clientes que tengan más de 5000 de
crédito disponible.

También podemos utilizar las columnas de cálculo en comparaciones como vemos en la figura
4.14.

31
Asignatura: Sistemas de Base de Datos

select codiClien,nombreClien,(limiCreClien-balanClien)as CrediDisClien


from tCliente where (limiCreClien-balanClien)>5000;

Figura 4.14. Comando SELECT con un cálculo en la condición.

Operador LIKE
En la mayoría de los casos, en las condiciones de las cláusulas WHERE hay coincidencias exactas,
como recuperar filas de los clientes situados en la ciudad de Grove. Sin embargo, en algunos casos
las coincidencias exactas no funcionan. Por ejemplo, podríamos saber que el valor deseado
contiene sólo un conjunto determinado de caracteres. En esos casos, utilizaremos el operador
LIKE con un símbolo de porcentaje, como vemos en el ejemplo 12. En lugar de buscar la igualdad,
el operador LIKE utiliza uno o más caracteres de porcentaje para buscar una coincidencia a partir
de un modelo.

Ejemplo 12
Liste el código, nombre y dirección completa de los clientes situados en una calle que contenga las
letras “Central”.

Todo lo que sabemos es que las direcciones que queremos contienen un conjunto determinado
de caracteres (“Central”) en alguna parte de la columna direcClien, pero no sabemos dónde. En
SQL para Oracle y para SQL Server, el signo de porcentaje (%) se utiliza como comodín para
representar cualquier conjunto de caracteres. Como vemos en la figura 4.15, la condición LIKE
‘%Central%’ recupera información de los clientes cuya calle contiene un conjunto de caracteres,
seguidos de las letras “Central”, seguidas posteriormente por algunos caracteres adicionales.
Observe que esta consulta también recuperaría información de un cliente cuya calle es “123
Centralia”, porque “Centralia” también contiene las letras “Central”.

select codiClien,nombreClien,direcClien from tCliente where direcClien


like '%central%';

Figura 4.15. Comando SELECT con un operador LIKE y comodines.

Otro símbolo comodín en SQL es el guión bajo (_), que representa cualquier carácter individual.
Por ejemplo, “T_m” representa la letra “T” seguida de cualquier carácter, seguido de la letra “m”,
y recuperaría filas en que se incluyeran las palabras Tim, Tom o T3m.

31
Asignatura: Sistemas de Base de Datos

Nota: En una base de datos grande sólo debemos utilizar los comodines cuando sea
absolutamente necesario. Las búsquedas con comodines pueden ser extremadamente lentas para
el proceso.

Operador IN
Una cláusula IN, que consiste en el operador IN seguido de un conjunto de valores, proporciona
una manera concisa de escribir ciertas condiciones, como ilustra el ejemplo 13. Más adelante
veremos otro uso de la cláusula IN en ejemplos más complejos.

Ejemplo 13
Liste el código, nombre y límite de crédito de cada cliente que tenga un límite de crédito de
$5000, $10000 y $15000.

En esta consulta podemos utilizar una cláusula IN para determinar si un límite de crédito es
$5000, $10000 o $15000. Obtendremos la misma respuesta utilizando la condición WHERE
limiCreClien = 5000 OR limiCreClien = 10000 OR limiCreClien = 15000. El método que vemos en la
figura 4.17 es más sencillo porque la cláusula IN contiene un conjunto de valores: 5000, 10000 y
15000. La condición es verdadera para aquellas filas en que el valor de la columna limiCreClien
esté en ese conjunto.

select codiClien,nombreClien,limiCreClien from tCliente


where limiCreClien=5000 or limiCreClien=10000 or limiCreClien=15000;

Figura 4.17. Comando SELECT con una cláusula IN.

Ordenar
El orden de las filas en una tabla es inmaterial para el DBMS. Desde un punto de vista práctico,
esto significa que cuando consultamos una base de datos relacional, no hay ningún orden definido
en el que mostrar los resultados. Las filas se pueden mostrar en el orden en que se introdujeron
originalmente los datos, pero ni siquiera esto es del todo cierto. Si el orden en que se muestran
los datos es importante, podemos solicitar expresamente que los resultados aparezcan en un
orden deseado. En SQL especificaremos el orden de los resultados utilizando la cláusula ORDER
BY.

Cláusula ORDER BY

31
Asignatura: Sistemas de Base de Datos

Utilizamos la cláusula ORDER BY para listar datos en un orden específico, como vemos en el
ejemplo 14.

Ejemplo 14
Liste el código, nombre y balance de los clientes. Ordene el resultado en orden ascendente
(aumentando) por balance.

La columna según la que ordenamos los datos se denomina clave de ordenación o simplemente
clave. En el ejemplo 14 tenemos que ordenar el resultado por balance, por tanto la clave de
ordenación es la columna balanClien. Para ordenar el resultado utilice la cláusula ORDER BY
seguida de la clave de ordenación. Si no especificamos un orden, por defecto será ascendente. La
consulta aparece en la figura 4.18.

SELECT codiClien,nombreClien,balanClien
FROM tCliente
order by balanClien asc;

Figura 4.18. Comando SELECT para obtener filas.

Opciones adicionales para ordenar


En ocasiones podemos necesitar ordenar datos utilizando más de una clave, como vemos en el
ejemplo 15.

Ejemplo 15
Liste el código, nombre y límite de crédito de todos los clientes. Ordénelos por límite de crédito
en orden descendente y después por nombre. (En otras palabras primero ordene los clientes con
límite de crédito en orden descendente. Dentro de cada grupo de clientes con el mismo límite de
crédito, ordénelos por nombre en orden ascendente.)

En el ejemplo 15 tenemos dos nuevos conceptos: ordenar por varias claves (limiCreClien y
nombreClien) y ordenar una de las claves en orden descendente. Cuando tenemos que ordenar
datos por dos columnas, la columna más importante (en este caso, limiCreClien) se denomina
clave principal de ordenación y la columna menos importante (en este caso, nombreClien) se

31
Asignatura: Sistemas de Base de Datos

denomina clave secundaria de ordenación. Para ordenar por múltiples claves, listaremos las
claves por orden de importancia en la cláusula ORDER BY. Para clasificar en orden descendente,
después del nombre de la clave de ordenación situaremos el operador DESC, como vemos en la
figura 4.19.

select codiClien,nombreClien,limiCreClien
from tCliente
order by limiCreClien desc, nombreClien;

Figura 4.19. Comando SELECT para ordenar datos por múltiples claves de ordenación.

Funciones
SQL utiliza funciones especiales, denominadas funciones de agregación, para calcular sumas,
medias, recuentos, valores máximos y valores mínimos. Estas funciones se aplican a grupos de
filas. Se podrían aplicar a todas las filas de una tabla (por ejemplo, calcular el balance medio de
todos los clientes). También se pueden aplicar a aquellas filas que cumplan una condición
determinada (por ejemplo, el balance medio de todos los clientes del vendedor 20). Las
descripciones de las funciones de agregación se recogen en la tabla 4.3.

Función Descripción
AVG Calcula el valor medio en una columna.
COUNT Determina el número de filas en una tabla.
MAX Determina el valor máximo en una columna.
MIN Determina el valor mínimo en una columna.
SUM Calcula el total de los valores en una columna.
Tabla 4.3. Operadores aritméticos.

Función COUNT
La función COUNT, como vemos en el ejemplo 16, cuenta el número de filas en una tabla.

Ejemplo 16

31
Asignatura: Sistemas de Base de Datos

¿Cuántos artículos hay con la clase de artículo HW?

Para esta consulta tenemos que determinar el número total de filas en la tabla tArtículo con el
valor HW en la columna claseArti. Podemos contar los números de artículos en los resultados de
las consultas, o el número de descripción de los artículos, o el número de entradas en cualquier
otra columna. Es independiente la columna que elijamos, porque todas nos darán la misma
respuesta. En lugar de elegir arbitrariamente una columna, la mayoría de las implantaciones de
SQL nos permiten utilizar el asterisco (*) para representar cualquier columna, como vemos en la
figura 4.20.

Figura 4.20. Comando SELECT para contar filas.

También podemos contar el número de filas en una consulta seleccionando una columna
determinada en lugar de utilizar el asterisco, de esta manera:

SELECT COUNT(codiArti)
FROM tArticulo
WHERE claseArti = 'HW';

Función SUM
Si necesitamos calcular el total de los balances de todos los clientes, podemos utilizar la función
SUM, como vemos en el ejemplo 17.

Ejemplo 17
Encuentra el número total de clientes de Premiere Products y el total de sus balances.

Cuando utilizamos la función SUM, debemos especificar la columna que hay que sumar, y el tipo
de datos de la columna ha de ser numérico. (¿Cómo calcular la suma de nombres o dirección?) En
la figura 4.21 vemos la consulta.

Figura 4.21. Comando SELECT para contar filas y calcular el total.

31
Asignatura: Sistemas de Base de Datos

Función AVG, MAX y MIN


El uso de las funciones AVG, MAX y MIN es similar al de SUM, excepto que se calculan diferentes
estadísticas. AVG calcula el valor medio en un rango numérico, MAX calcula el valor máximo en un
rango numérico y MIN calcula el valor mínimo en un rango numérico.

Ejemplo 18
Encuentra la suma de todos los balances, el balance medio, el balance máximo y el balance
mínimo de todos los clientes de Premiere Products.

En la figura 4.22 vemos la consulta y los resultados.

Nota: Cuando utilizamos las funciones SUM, AVG, MAX o MIN, SQL ignora los valores nulos en la
columna y los elimina de los cálculos.

Los valores nulos en columnas numéricas pueden producir resultados extraños cuando se calculan
las estadísticas. Suponiendo que la columna balanClien aceptara valores nulos, hay cuatro clientes
en la tabla tCliente y sus respectivos balances son $100, $200, $300 y nulo (desconocido). Cuando
calculamos el balance medio, SQL ignora el valor nulo y obtiene el resultado de $200(($100+
$200+$300)/3). De manera similar, cuando calculamos el total de los balances, SQL ignora el valor
nulo y calcula un total de $600. Sin embargo, cuando contamos el número de clientes en una
tabla, SQL incluye la fila que contiene el valor nulo y el resultado es 4. Así, el total de los balances
($600) dividido por el número de clientes (4) resulta un balance medio de $150.

Figura 4.22. Comando SELECT con varias funciones.

Nota: Podemos utilizar una cláusula AS con una función. Por ejemplo, el siguiente comando
calcula la suma de la columna balanClien y muestra el encabezado de la columna como
balanToClien en los resultados de la consulta:

SELECT SUM(balanClien) AS balanToClien


FROM tCliente;

Operador DISTINCT
En algunas situaciones, el operador DISTINCT es útil cuando se utiliza junto con la función COUNT,
porque elimina valores duplicados en los resultados de la consulta. Los ejemplos 19 y 20 ilustran
los usos más comunes del operador DISTINCT.

Ejemplo 19
Encuentra el código de todos los clientes que tienen actualmente un pedido abierto (es decir, un
pedido actualmente en la tabla tPedido).

31
Asignatura: Sistemas de Base de Datos

El comando parece bastante sencillo. Cuando un cliente tiene actualmente un pedido abierto,
debe haber al menos una fila en la tabla tPedido en la que aparezca el número de ese cliente.

Podríamos utilizar la consulta que aparece en la figura 4.23 para encontrar los números de
clientes con pedidos abiertos.

Figura 4.23. Códigos de los clientes con pedidos abiertos.

Observe que los códigos de clientes 148 y 608 aparecen más de una vez en los resultados, lo que
significa que actualmente ambos tienen más de un pedido abierto en la tabla tPedido. En el
ejemplo 20 vamos a listar cada cliente sólo una vez.

Ejemplo 20
Encuentre el código de cada cliente que tiene actualmente un pedido abierto. Liste cada cliente
sólo una vez.

Para asegurar la exclusividad, podemos utilizar el operador DISTINCT, como vemos en la figura
4.24.

Se puede estar preguntando sobre la relación entre COUNT y DISTINCT, porque en ambos hay filas
de recuento. En el ejemplo 21 se identifican las diferencias.

Ejemplo 21
Cuente el código de clientes que tienen actualmente pedidos abiertos.

La consulta de la figura 4.25 cuenta el número de clientes que utilizan la columna codiClien.

31
Asignatura: Sistemas de Base de Datos

Figura 4.24. Número de cliente con pedidos abiertos y con los duplicados eliminados.

Figura 4.25. Recuento que incluye códigos de cliente duplicados.

Preguntas y Respuestas

 Pregunta: ¿Qué problema hay en los resultados de la consulta de la figura 4.25?


 Respuesta: La respuesta, 7, es el resultado de contar los clientes que tienen pedidos abiertos
varias veces, una vez por cada pedido abierto actualmente. El resultado cuenta cada número
de cliente y no elimina los números de cliente duplicados para proporcionar un recuento
exacto del número de clientes.

Algunas implantaciones de SQL, incluyendo Oracle y SQL Server, nos permiten utilizar el operador
DISTINCT para calcular el recuento correcto, como vemos en la figura 4.26.

Anidar Consultas
En ocasiones, son necesarios dos o más pasos para obtener los resultados que necesitamos, como
vemos en los siguientes dos ejemplos.

Figura 4.26. Recuento que excluye códigos de cliente duplicados (utilizando DISTINCT dentro de
COUNT).

Ejemplo 22
Liste el código de cada artículo con la clase AP.

31
Asignatura: Sistemas de Base de Datos

En la figura 4.27 vemos el comando para obtener la respuesta.

Figura 4.27. Seleccionar todos los artículos con la clase AP.

Ejemplo 23
Liste los códigos de pedido que contienen una línea de pedido para un artículo con la clase AP.

En el ejemplo 23 tenemos que encontrar los códigos de pedido en la tabla tDetallePedido que
correspondan a los códigos de artículos en los resultados de la consulta del ejemplo 22. Una vez
obtenidos dichos resultados (CD52, DR93, DW11, KL62 y KT03), podemos utilizar el comando de la
figura 4.28.

Figura 4.28. Consulta utilizando los resultados de la figura 4.27.

Subconsultas
Es posible situar una consulta dentro de otra. La consulta interior se denomina subconsulta. La
subconsulta se evalúa primero. Una vez evaluada la subconsulta, la consulta exterior puede
utilizar los resultados de la subconsulta para encontrar los suyos propios, como vemos en el
ejemplo 24.

31
Asignatura: Sistemas de Base de Datos

Ejemplo 24
Encuentre la respuesta a los ejemplos 22 y 23 en un solo paso.

Podemos encontrar el mismo resultado de los dos ejemplos anteriores en un solo paso utilizando
una subconsulta. En la figura 4.29 el comando entre paréntesis es la subconsulta. Esta subconsulta
se evaluará primero, produciendo una tabla temporal. La tabla temporal se utiliza solo para
evaluar la consulta: no está disponible para mostrar al usuario, y se borrará una vez que la
evaluación de la consulta haya finalizado. En este ejemplo la tabla temporal tiene una sola
columna (codiArti) y cinco filas (CD52, DR93, DW11, KL62 y KT03). La consulta exterior se evaluará
después. En este caso, la consulta exterior recupera el número de pedido de cada fila de la tabla
tDetallePedido, para la que el código de artículo está en los resultados de la subconsulta. Como la
tabla contiene sólo los códigos de artículo en la clase AP, los resultados muestran la lista deseada
de números de pedido.

En la figura 4.29 vemos números de pedido duplicados en los resultados. Para eliminar esta
duplicación, podemos utilizar el operador DISTINCT de esta manera:

SELECT DISTINCT(codiPedi)
FROM tDetallePedido
WHERE codiArti IN
(SELECT codiArti FROM tArticulo WHERE claseArti = ‘AP’);

Figura 4.29. Operador IN y subconsulta.

Los resultados de esta consulta mostrarán cada código de pedido sólo una vez.

Ejemplo 25
Liste el código, nombre y balance de cada cliente cuyo balance excede el balance medio de todos
los clientes.

31
Asignatura: Sistemas de Base de Datos

En este caso, utilizamos una subconsulta para obtener el balance medio. Como esta subconsulta
produce un solo número, podemos comparar el balance de cada cliente con este número, como
vemos en la figura 4.30.

Figura 4.30. Consulta con un operador y una subconsulta.

Nota: No se puede utilizar la condición balanClien > AVG(balanClien) en la cláusula WHERE, es


necesario utilizar una subconsulta para obtener el balance medio. Después se pueden utilizar los
resultados de la subconsulta en una condición, como se ilustra en la figura 4.30.

Agrupamiento
El agrupamiento crea grupos de filas que comparten alguna característica en común. Si
agrupamos clientes por límite de crédito, por ejemplo, el primer grupo contiene clientes con
límites de $5000, el segundo contiene clientes con límites de crédito de $7500, etc. Si, por otro
lado, agrupamos clientes por número de vendedor, el primer grupo contiene los clientes
representados por el código de vendedor 20, el segundo grupo contiene los representados por el
código 35, y el tercer grupo contiene los clientes representados por el código de vendedor 65.
Cuando agrupamos filas, todos los cálculos indicados en el comando SELECT se llevan a cabo para
todo el grupo. Por ejemplo, si agrupamos clientes por código de vendedor y la consulta solicita el
balance medio, los resultados incluyen el balance medio del grupo de clientes representados por
el código de vendedor 20, el balance medio del grupo del código de vendedor 35 y el balance
medio del grupo representado por el código de vendedor 65. Los siguientes ejemplos ilustran este
proceso.

Cláusula GROUP BY
La cláusula GROUP BY nos permite agrupar datos de una columna en concreto, como codiVende,
y calcular estadísticas cuando lo deseemos, como vemos en el ejemplo 26.

Ejemplo 26
Liste el código de todos los vendedores y el balance medio de sus clientes.

31
Asignatura: Sistemas de Base de Datos

Como tenemos que agrupar clientes por código de vendedor y después calcular el balance medio
de todos los clientes en cada grupo, usaremos la cláusula GROUP BY. En este caso, GROUP BY
codiVende sitúa a los clientes con el mismo código de vendedor en grupos separados. Las
estadísticas indicadas en el comando SELECT se calculan para cada grupo. Es importante tener en
cuenta que la cláusula GROUP BY no ordena los datos en un orden en concreto, tenemos que
utilizar la cláusula ORDER BY para ordenar datos. Asumiendo que los resultados deberían
ordenarse por el código de vendedor, podemos utilizar el comando de la figura 4.31.

Figura 4.31. Agrupar registros en una columna.

Cuando se agrupan las filas, se produce una línea de resultados para cada grupo. Sólo se pueden
mostrar estadísticas calculadas para el grupo de columnas cuyos valores son los mismos para
todas las filas de un grupo.

Preguntas y respuestas

 Pregunta: ¿Es adecuado mostrar el código de vendedor en la consulta del ejemplo 26?
 Respuesta: Sí, porque el código de vendedor en una fila de un grupo ha de ser el mismo que
el código de vendedor en cualquier otra fila de grupo.
 Pregunta: ¿Sería adecuado mostrar el código de cliente en la consulta del ejemplo 26?
 Respuesta: No, porque el código de cliente varía en las filas de un grupo. (El mismo vendedor
está asociado con muchos clientes.) El DBMS no podría determinar qué número de cliente
mostrar para el grupo, y mostraría un mensaje de error si intentamos mostrar un código de
cliente.

Cláusula HAVING
La cláusula HAVING se utiliza para restringir los grupos que están incluidos, como vemos en el
ejemplo 27.

Ejemplo 27
Repita el ejemplo anterior, pero liste solo aquellos vendedores que representen menos de cuatro
clientes.

La única diferencia entre los ejemplos 26 y 27 es la restricción de mostrar solo aquellos clientes
que representen menos de cuatro clientes. La restricción no se aplica a filas individuales, sino a
grupos. Como la cláusula WHERE se aplica solo a filas, no podemos utilizarla para llevar a cabo el

31
Asignatura: Sistemas de Base de Datos

tipo de selección necesario. Por fortuna, la cláusula HAVING hace en los grupos lo que la cláusula
WHERE hace en las filas. La cláusula HAVING limita los grupos incluidos en los resultados. En la
figura 4.32, la fila creada para un grupo solo se muestra cuando el recuento del número de filas
del grupo es menor que cuatro y, además, todos los grupos están ordenados por número de
vendedor.

Figura 4.32. Restricción de grupos a incluir en los resultados.

HAVING frente a WHERE


Al igual que podemos utilizar la cláusula WHERE para limitar las filas incluidas en el resultado de
una consulta, podemos utilizar la cláusula HAVING para limitar los grupos incluidos. Los siguientes
ejemplos ilustran la diferencia entre estas dos cláusulas.

Ejemplo 28
Liste los límites de crédito y el código de clientes que tienen cada límite de crédito.

Para encontrar el código de clientes que tienen un límite de crédito determinado, tenemos que
agrupar los datos por límite de crédito, como vemos en la figura 4.33.

Figura 4.33. Contar el número de filas en cada grupo.

Ejemplo 29
Repita el ejemplo 28, pero liste sólo los límites de crédito que tengan más de un cliente.

La consulta incluye una cláusula HAVING porque esta condición implica un total de grupo, como
vemos en la figura 4.34.

31
Asignatura: Sistemas de Base de Datos

Figura 4.34. Muestra los grupos que contienen más de una fila.

Ejemplo 30
Liste cada límite de crédito y el código de clientes del vendedor 20 que tienen este límite.

La condición implica sólo las filas, por tanto es adecuado utilizar la cláusula WHERE, como vemos
en la figura 4.35.

Figura 4.35. Restringir las filas a agrupar.

Ejemplo 31
Repita el ejemplo 30, pero liste solo los límites de crédito que tengan más de un cliente.

Tenemos que utilizar una cláusula WHERE y una cláusula HAVING, porque las condiciones
implican filas y grupos, como vemos en la figura 4.36.

Figura 4.36. Restringir las filas y los grupos.

31
Asignatura: Sistemas de Base de Datos

En el ejemplo 31, las filas de la tabla original se evalúan sólo cuando el número de vendedor es
20. Estas filas se agrupan por límite de crédito y se calcula el recuento. Sólo se muestran los
grupos para los que el recuento calculado es mayor que uno.

Valores nulos
En ocasiones, una condición se refiere a una columna que puede aceptar valores nulos, como
vemos en el ejemplo 32.

Ejemplo 32
Liste el código y nombre de los clientes con un valor nulo (desconocido) de calle.

La condición debería ser algo como direcClien = NULL. El formato correcto realmente utiliza el
operador IS NULL (direcClien IS NULL), como vemos en la figura 4.37. (Para seleccionar un cliente
cuya calle no es nula, utilice el operador IS NOT NULL (direcClien IS NOT NULL)) En la actual base
de datos de Premiere Products, ningún cliente tiene un valor nulo de calle, por tanto, no se
recupera ninguna fila en los resultados de la consulta.

Figura 4.37. Seleccionar filas que contienen valores nulos en la columna direcClien.

31
Asignatura: Sistemas de Base de Datos

TEMA

5
CONSULTAS A MÚLTIPLES TABLAS
Introducción
En este capítulo aprenderemos a utilizar SQL para recuperar datos a partir de una o más
tablas.

Consultar múltiples tablas


En el capítulo anterior vimos cómo recuperar datos de una sola tabla. Muchas consultas requieren
la recuperación de datos de más de una tabla. Para recuperar datos de múltiples tablas, primero
tenemos que unir las tablas, y después formular una consulta utilizando los mismos comandos
que utilizamos para las consultas a una sola tabla.

Nota: En las siguientes consultas los resultados podrían contener las mismas filas, pero podrían
estar listadas en un orden diferente. Si el orden es importante, se puede incluir una cláusula
ORDER BY en la consulta para asegurar que los resultados están listados en el orden deseado.

Unir dos tablas


Para recuperar datos de más de una tabla, debemos unir las tablas entre sí encontrando en ellas
filas que tengan valores idénticos en columnas coincidentes. Podemos unir tablas utilizando una
condición en la cláusula WHERE, como veremos en el ejemplo 1.

Ejemplo 1
Liste el código y el nombre de todos los clientes, junto con el código, apellido y nombre del
vendedor que los representa.

Como los códigos y nombres de los clientes están en la tabla tCliente y códigos y nombres de los
vendedores están en la tabla tVendedor, tendremos que incluir ambas tablas en el comando SQL
para poder recuperar los datos de ambas tablas. Para unir (relacionar) las tablas, construiremos el
comando SQL de esta manera:

31
Asignatura: Sistemas de Base de Datos

1. En la cláusula SELECT, liste todas las columnas que quiera mostrar.


2. En la cláusula FROM, liste todas las tablas implicadas en la consulta.
3. En la cláusula WHERE, liste la condición que restringe los datos a recuperar a sólo las filas
de las dos tablas que coincidan, es decir, restrínjala a las filas que tengan valores comunes
en columnas coincidentes.

Como vimos anteriormente, normalmente es necesario calificar un nombre de columna para


especificar la columna en concreto a la que nos referimos. Calificar nombres de columna es
especialmente importante al unir tablas, porque debemos unir las tablas en columnas
coincidentes que suelen tener nombres de columna idénticos. Para calificar un nombre de
columna, preceda el nombre de la columna con el nombre de la tabla, seguido en un punto. Las
columnas coincidentes en este ejemplo son las que se llaman codiVende: Hay una columna en la
tabla tVendedor llamada codiVende y una columna en la tabla tCliente que también se llama
codiVende. La columna codiVende de la tabla tVendedor se escribe como tVendedor.codiVende y
la columna codiVende de la tabla tCliente se escribe tCliente.codiVende. En la figura 5.1 vemos la
consulta y sus resultados.

Cuando existe una ambigüedad potencial al listar nombres de columnas, es necesario calificar las
columnas implicadas en la consulta. También se pueden calificar otras columnas, incluso cuando
no hay confusión posible. Algunos usuarios prefieren calificar todos los nombres de columnas,
pero en este libro solo calificaremos nombres de columnas cuando sea necesario.

select codiClien,nombreClien,tCliente.codiVende,apeVende,nombreVende
from tCliente, tVendedor where tCliente.codiVende=tVendedor.codiVende;

Figura 5.1. Unir dos tablas con un solo comando SQL.

Preguntas y Respuestas

 Pregunta: En la primera fila del resultado de la figura 5.1, el código de cliente es 148, y el
nombre de cliente es Al’s Appliance and Sport. Estos valores representan la primera fila de la
tabla tCliente. ¿Por qué el código de vendedor es 20, el apellido del vendedor Kaiser y su
nombre Valerie?

31
Asignatura: Sistemas de Base de Datos

 Respuesta: En la tabla tCliente el código de vendedor para el código de cliente 148 es 20.
(Esto indica que el código de cliente 188 está relacionada con el código de vendedor 20) En la
tabla tVendedor, el apellido del código de Vendedor 20 es Kaiser y su nombre Valerie.

Ejemplo 02
Liste el código y nombre de los clientes cuyo límite de crédito sea 7500, junto con el código,
apellido y nombre del vendedor que representa al cliente.

En el ejemplo 1 utilizamos una condición en la cláusula WHERE sólo para relacionar un cliente con
un vendedor para unir las tablas. Aunque relacionar un cliente con un vendedor es esencial en
este ejemplo también, tenemos que restringir los resultados a solo aquellos clientes cuyo límite
de crédito sea 7500. Podemos restringir las filas utilizando una condición compuesta, como vemos
en la figura 5.2.

select codiClien,nombreClien,tCliente.codiVende,apeVende,nombreVende
from tCliente,tVendedor where tCliente.codiVende=tVendedor.codiVende
and limiCreClien=7500;

Figura 5.2. Restringir las filas en una unión.

Ejemplo 3
Para cada artículo pedido, liste el código de pedido, el código de artículo, la descripción del
artículo, el número de unidades pedidas, el precio cotizado y el precio unitario.

Un artículo se considera pedido cuando hay una fila en la tabla tDetallePedido en la que aparece
el artículo. Podemos encontrar el código de pedido, el número de unidades pedidas y el precio
cotizado en la tabla tDetallePedido. Sin embargo, para encontrar la descripción del artículo y el
precio unitario, tenemos que buscar en la tabla tArticulo. Después tenemos que buscar filas en la
tabla tDetallePedido y filas en la tabla tArticulo que coincidan (filas que contengan el mismo
código de artículo). En la figura 5.3 vemos la consulta y sus resultados.

select codiPedi,tArticulo.codiArti,descripArti,cantiArti,precioCoArti,
precioUArti
from tDetallePedido, tArticulo
where tDetallePedido.codiArti=tArticulo.codiArti;

31
Asignatura: Sistemas de Base de Datos

Figura 5.3. Unir las tablas tDetallePedido y tArticulo.

Preguntas y Respuestas

 Pregunta: ¿Se puede utilizar tArticulo.codiArti en lugar de tDetallePedido.codiArti en la


cláusula SELECT?
 Respuesta: Sí. Los valores de esas dos columnas coinciden porque han de cumplir la condición
tDetallePedido.codiArti = tArticulo.codiArti.

Comparación de uniones, IN y EXISTS


En SQL unimos tablas incluyendo una condición en la cláusula WHERE para asegurarnos de que las
columnas coincidentes contienen valores iguales (por ejemplo, tDetallePedido.codiArti =
tArticulo.codiArti). Podemos obtener resultados similares utilizando el operador IN o el operador
EXISTS con una subconsulta. La elección entre uno u otro depende de sus preferencias personales,
porque con cualquiera de las dos opciones obtendremos los mismos resultados.

En los siguientes ejemplos veremos el uso de cada operador.

Ejemplo 4
Busque la descripción de los artículos que estén incluidas en el código de pedido 21610.

Como la consulta también implica recuperar datos de las tablas tDetallePedido y tArticulo (como
vimos en el ejemplo 3), podemos hacerlo de manera similar. Sin embargo, hay dos diferencias
básicas entre los ejemplos 3 y 4. En primer lugar, la consulta del ejemplo 4 no requiere tantas
columnas, y en segundo lugar, sólo interviene el código de pedido 21610. Al tener menos
columnas que recuperar habrá menos columnas listadas en la cláusula SELECT. Podemos restringir
la consulta a un solo pedido añadiendo la condición codiPedi=’21610’ a la cláusula WHERE. En la
figura 5.4 vemos la consulta y sus resultados. Observe que la tabla tDetallePedido está listada en
la cláusula FROM, aunque no sea necesario mostrar ninguna columna de la tabla tDetallePedido.
La cláusula WHERE contiene columnas de la tabla tDetallePedido, por tanto es necesario incluir la
tabla en la cláusula FROM.

Operador IN
Otra manera de recuperar datos de múltiples tablas en una consulta es utilizando el operador IN
con una subconsulta. En el ejemplo 4, primero, podríamos utilizar una subconsulta para encontrar
todos los códigos de artículo en la tabla tDetallePedido que aparecen en todas las filas en las que

31
Asignatura: Sistemas de Base de Datos

el código de Pedido sea 21610. Después podemos encontrar la descripción del artículo de todos
los artículos cuyo código esté en la lista. En la figura 5.5 vemos la consulta y sus resultados.

select tArticulo.descripArti
from tArticulo,tDetallePedido
where tArticulo.codiArti=tDetallePedido.codiArti
and codiPedi=21610;

Figura 5.4. Restringir las filas al unir las tablas tDetallePedido y tArticulo.

select descripArti from tArticulo


where codiArti in
(select codiArti
from tDetallePedido
where codiPedi=21610);

Figura 5.5. Utilizar el operador IN en lugar de unir dos tablas para consultarlas.

En la figura 5.5, al evaluar la subconsulta se produce una tabla temporal que consiste en los
códigos de artículo (DR93 y DW11) que están presentes en el código de pedido 21610. Al ejecutar
el resto de la consulta se producen las descripciones del artículo para cada artículo cuyo código
está en la tabla temporal, en este caso, Gas Range (DR93) y Washer (DW11).

Operador EXISTS
También podemos utilizar el operador EXISTS para recuperar datos desde más de una tabla, como
vemos en el ejemplo 5. El operador EXISTS comprueba la existencia de filas que cumplan algunos
criterios.

Ejemplo 5
Busque el código de pedido y la fecha de todos los pedidos que contengan el código de artículo
DR93.

Esta consulta es similar a la del ejemplo 4, pero esta vez implica a la tabla tPedido en lugar de la
tabla tArticulo. En este caso, podemos escribir la consulta de cualquiera de las dos maneras que
hemos visto. Por ejemplo, podríamos utilizar el operador IN con una subconsulta, como vemos en
la figura 5.6.

31
Asignatura: Sistemas de Base de Datos

SELECT codiPedi, fechaPedi


from tPedido
where codiPedi in
(select codiPedi from tDetallePedido where codiArti='DR93');

Figura 5.6. Operador IN para seleccionar información del pedido.

Otro método de resolver el ejemplo 5 es con el operador EXISTS, como vemos en la figura 5.7.

Figura 5.7. Operador EXISTS para seleccionar información del pedido.

La subconsulta de la figura 5.7 es la primera que hemos visto que implica a una tabla listada en la
consulta exterior. Este tipo de consulta se denomina subconsulta correlacionada. En este caso se
utiliza en la subconsulta la tabla tPedido, que está listada en la cláusula FROM de la consulta
exterior. Por este motivo tenemos que calificar la columna codiPedi en la subconsulta
(tPedido.codiPedi). En las consultas anteriores con el operador IN no era necesario calificar las
columnas.

La consulta que vemos en la figura 5.7 funciona de esta manera: para cada fila de la tabla tPedido,
la subconsulta se ejecuta utilizando el valor de tPedido.codiPedi que ocurre en esa fila. La
consulta interior produce una lista de todas las filas de la tabla tDetallePedido en las que
tDetallePedido.codiPedi coincida con este valor y en las que codiArti sea igual a DR93. Podemos
preceder una subconsulta del operador EXISTS para crear una condición que será verdadera si se
obtienen una o más filas cuando se ejecuta la subconsulta o de lo contrario la condición será falsa.

Para comprender mejor el proceso, considere los códigos de pedido 21610 y 21613 de la tabla
tPedido. El código de pedido 21610 se incluye porque existe una fila en la tabla tDetallePedido
con este código de pedido y el código de artículo DR93. Cuando se ejecuta la subconsulta, habrá al
menos una fila en los resultados, que a su vez hacen que la condición EXISTS sea verdadera. Sin
embargo, el código de pedido 21613 no se incluirá, porque no existe ninguna fila en la tabla
tDetallePedido con este código de pedido y el código de artículo DR93. No habrá ninguna fila en
los resultados de la subconsulta, lo que a su vez hace que la condición EXISTS sea falsa.

Subconsulta dentro de subconsulta


Podemos utilizar SQL para crear una subconsulta anidada (una subconsulta dentro de otra
subconsulta), como vemos en el ejemplo 6.

Ejemplo 6

31
Asignatura: Sistemas de Base de Datos

Busque el código y la fecha de los pedidos que incluyan un artículo situado en el almacén 3.

Una manera de solucionar este problema es primeramente determinado la lista de códigos de


artículo en la tabla tArticulo de los artículos situados en el almacén 3. Después obtendremos una
lista de códigos de pedido de la tabla tDetallePedido con un código de artículo correspondiente en
la lista de códigos de artículo. Por último, recuperaremos esos números y fechas de pedido de la
tabla tPedido para los que el código de pedido esté en la lista de códigos de pedido obtenidos
durante el segundo paso. La consulta y sus resultados aparecen en la figura 5.8.

select codiPedi, fechaPedi


from tPedido
where codiPedi in
(select codiPedi
from tDetallePedido
where codiArti in
(select codiArti
from tArticulo
where almaArti=3));

Figura 5.8. Subconsultas anidadas (una subconsulta dentro de otra).

Como se puede esperar, SQL evalúa las consultas desde la más interior hasta la más exterior. La
consulta de este ejemplo se evalúa en tres pasos:

1. La subconsulta interior es la primera que se evalúa, produciendo una tabla temporal de


códigos de artículo para aquellos artículos situados en el almacén 3.
2. Después se evalúa la siguiente subconsulta (intermedia), produciendo una segunda tabla
temporal con una lista de códigos de pedido. Cada código de pedido de este conjunto
tiene una fila en la tabla tDetallePedido para la que el código de artículo está en la tabla
temporal producida en el paso 1.
3. La consulta exterior se evalúa en último lugar, produciendo la lista deseada de códigos y
fechas de pedido. Sólo se incluyen en los resultados los pedidos cuyos códigos estén en la
tabla temporal producida en el paso 2.

Otra manera de resolver el ejemplo 6 sería uniendo las tablas tPedido, tDetallePedido y tArticulo.
En la figura 5.9 vemos la consulta y sus resultados.

select tPedido.codiPedi,fechaPedi
from tPedido, tDetallePedido,tArticulo
where tPedido.codiPedi=tDetallePedido.codiPedi

31
Asignatura: Sistemas de Base de Datos

and tDetallePedido.codiArti=tArticulo.codiArti
and almaArti=3;

Figura 5.9. Unir tres tablas.

En esta consulta las tablas se unen con las siguientes condiciones:

tDetallePedido.codiPedi = tPedido.codiPedi
tDetallePedido.codiArti = tArticulo.codiArti

La condición almaArti = ‘3’ restringe el resultado a solo aquellas partidas situadas en el almacén 3.

Los resultados de las consultas son correctos, independientemente de qué comando utilicemos.
Podemos utilizar el método que prefiramos. Pero, ¿hay alguno que sea más eficaz que el otro?
SQL lleva a cabo muchas optimizaciones predefinidas que analizan las consultas para determinar
la mejor manera de satisfacerlas. Con un buen optimizador, en principio la manera de formular
una consulta no debería ser muy relevante, en este caso las subconsultas anidadas pueden llevar
algo más de tiempo que la unión de tablas. Sin embargo, si utilizamos un DBMS sin optimizador, la
manera de escribir una consulta puede suponer una diferencia importante en la velocidad a la
que el DBMS ejecuta la consulta. Cuando trabajamos con una base de datos muy grande y la
eficiencia es fundamental, es recomendable consultar el manual del DBMS o probar algunos
tiempos. Intente ejecutar la misma consulta de las dos maneras para ver si observa diferencias en
velocidad de ejecución. En base de datos pequeñas no debería haber una diferencia significativa
de tiempo entre los dos métodos.

Ejemplo práctico
En la consulta del ejemplo 7 intervienen varias de las funciones que ya hemos visto. Aparecen en
ella las principales cláusulas que se pueden utilizar en un comando SELECT. También se ve el
orden en que las cláusulas han de aparecer.

Ejemplo 7
Liste el código de cliente, código de pedido, fecha de pedido y total de todos los pedidos que
excedan de 1000. Asigne el nombre de columna TotalPedido a la columna que muestre los totales
del pedido.

En la figura 5.10 vemos la consulta y sus resultados. En esta consulta, las tablas tPedido y
tDetallePedido se unen al listarlas en la cláusula FROM y relacionarlas en la cláusula WHERE. Los
datos seleccionados están ordenados por código de pedido utilizando la cláusula ORDER BY. La
cláusula GROUP BY indica que los datos se deben agrupar por código de pedido, código de cliente
y fecha de pedido. Para cada grupo, la cláusula SELECT muestra el código de cliente, el código de
pedido, la fecha de pedido y el total (SUM(cantiArti*PrecioCoArti)). Además, el total se ha
renombrado como TotalPedido. Sin embargo, no se mostrarán todos los grupos. La cláusula
HAVING muestra solo los grupos cuyo (SUM(cantiArti*PrecioCoArti)) es mayor que 1000.

31
Asignatura: Sistemas de Base de Datos

select codiClien,tPedido.codiPedi,fechaPedi,
(SUM(cantiArti*precioCoArti))as TOTAL
from tDetallePedido,tPedido
where tDetallePedido.codiPedi=tPedido.codiPedi
GROUP BY codiClien,tPedido.codiPedi,fechaPedi
HAVING SUM(cantiArti*precioCoArti)>1000;

Figura 5.10. Ejemplo práctico.

El código de pedido, nombre de cliente y fecha de pedido son únicos para cada pedido. Por tanto,
podría parecer que simplemente agrupando por código de pedido será suficiente. SQL requiere
que tanto el código de cliente como la fecha de pedido estén listados en la cláusula GROUP BY.
Recuerde que una cláusula SELECT puede incluir estadísticas calculadas para sólo los grupos o
columnas cuyos valores sean idénticos en cada fila de un grupo. Estableciendo que los datos se
agrupen por código de pedido, nombre de cliente y fecha de pedido, estamos indicando a SQL
que los valores de esas columnas deben ser iguales en cada fila de un grupo.

Alias
Cuando se listan las tablas en la cláusula FROM, podemos asignar a cada tabla un alias, o nombre
alternativo, que podemos utilizar en el resto de la declaración. Un alias se crea escribiendo el
nombre de la tabla, pulsando la barra espaciadora y después escribiendo el nombre del alias. No
es necesario separar ambos nombres con comas ni puntos.

Los alias se utilizan a efectos de simplificar. En el ejemplo 8 asignaremos a la tabla tVendedor el


alias V y a la tabla tCliente el alias C. De esta manera, podemos escribir el resto de la consulta V en
lugar de tVendedor y C en lugar de tCliente.

La consulta de este ejemplo es muy sencilla y, por tanto, las ventajas no son obvias, pero cuando
una consulta es completa y requiere que califiquemos los nombres, el uso de alias puede
simplificar el proceso considerablemente.

Ejemplo 8
Liste el código, apellido y nombre de todos los vendedores junto con el código y nombre de los
clientes a los que representa.

En la figura 5.11 vemos la consulta y su resultado utilizando alias.

SELECT V.codiVende,apeVende,codiClien,nombreClien
FROM tCliente C,tVendedor V
WHERE C.codiVende=V.codiVende;

31
Asignatura: Sistemas de Base de Datos

Figura 5.11. Alias en una consulta.

Nota: Técnicamente, no es necesario calificar codiClien, porque solamente se incluye en la tabla


tCliente. En la figura 5.11 la calificamos solamente para demostrar el efecto.

Unir una tabla así misma


Una segunda situación para utilizar un alias es unir una tabla así misma, lo que se denomina una
auto unión, como vemos en el ejemplo 9.

Ejemplo 9
Para cada par de clientes situados en la misma ciudad, muestre el código de cliente, el nombre de
cliente y la ciudad.

Si tuviéramos dos tablas separadas para clientes y la consulta solicitara clientes de la primera
tabla que tuvieran la misma ciudad que clientes de la segunda tabla, podríamos utilizar una
operación de unión normal para encontrar la respuesta. Sin embargo, en este caso solamente hay
una tabla (tCliente) que almacena toda la información de los clientes.

Para la consulta, podemos tratar a la tabla tCliente como si fueran dos tablas, creando un alias,
como vemos en el ejemplo 8. En este caso, podemos utilizar la siguiente cláusula FROM.

FROM tCliente P, tCliente S

SQL trata a esta cláusula como una consulta de dos tablas: una que tiene el alias P (Primero) y otra
con el alias S (Segundo). El hecho de que ambas tablas sean realmente la misma tabla tCliente no
supone ningún problema. En la figura 5.12 vemos la consulta y sus resultados.

SELECT P.codiClien,P.nombreClien,S.codiClien,S.nombreClien,P.ciudadClien
FROM tCliente P, tCliente S
WHERE P.ciudadClien=S.ciudadClien
AND P.codiClien>S.codiClien
ORDER BY P.ciudadClien;

31
Asignatura: Sistemas de Base de Datos

Figura 5.12. Utilizar alias para una auto-unión.

Estamos solicitando un código de cliente y un nombre a la tabla P, seguidos de un código de


cliente y un nombre a la tabla S, y después la ciudad. (Puesto que la ciudad en la primera tabla
debe coincidir con la ciudad de la segunda, podemos seleccionar la ciudad de cualquiera de las
dos tablas.)

La cláusula WHERE contiene dos condiciones: las ciudades han de coincidir, el código de cliente de
la primera tabla debe ser menor que el código de cliente de la segunda tabla. Además, la cláusula
ORDER BY asegura que los datos queden ordenados por el primer código de cliente. En las filas
con el mismo primer código de cliente, los datos se ordenan además por el segundo código de
cliente.

Unir varias tablas


Se pueden unir varias tablas, como vemos en el ejemplo 10. Para cada una de las tablas que
unimos, debemos incluir una condición indicando cómo están relacionadas las columnas.

Ejemplo 10
Para cada artículo pedido, liste el código de artículo, la cantidad pedida, el código de pedido, la
fecha de pedido, el código de cliente y el nombre de cliente, junto con el apellido del vendedor
que representa a cada cliente.

Un artículo está pedido cuando aparece en cualquier fila de la tabla tDetallePedido. El código de
artículo, cantidad pedida y el código de pedido aparecen en la tabla tDetallePedido. Si estos
fueran todos los requisitos de la consulta, la escribiríamos así:

SELECT codiArti, cantiArti, codiPedi


FROM tDetallePedido;

Sin embargo, esta consulta no es suficiente. También necesitamos la fecha de pedido, que está en
la tabla tPedido; el código y nombre del cliente, que están en la tabla tCliente; y el apellido del
vendedor, que está en la tabla tVendedor. Así, tenemos que unir cuatro tablas: tDetallePedido,
tPedido, tCliente y tVendedor. El procedimiento para unir más de dos tablas es esencialmente el
mismo que se utiliza para unir dos tablas. La diferencia radica en que la condición en la cláusula
WHERE será un condición compuesta. En este caso, tendríamos que escribir la cláusula WHERE de
esta manera:

WHERE tPedido.codiPedi = tDetallePedido.codiPedi


AND tCliente.codiClien = tPedido.codiClien
AND tVendedor.codiVende = tCliente.codiVende

31
Asignatura: Sistemas de Base de Datos

La primera condición relaciona un pedido a una línea de pedido con un código de pedido
correspondiente. La segunda condición relaciona el cliente con el pedido con el código de cliente
correspondiente. La condición final relaciona el vendedor a un cliente con un código de vendedor
coincidente. Para la consulta completa, listaremos todas las columnas deseadas en la cláusula
SELECT y calificaremos las columnas que aparezcan en más de una tabla. En la cláusula FROM,
listaremos las tablas implicadas en la consulta. En la figura 5.16 vemos la consulta y sus
resultados.

SELECT codiArti,cantiArti,tPedido.codiPedi,
fechaPedi,tCliente.codiClien,nombreClien,apeVende
FROM tDetallePedido,tPedido,tCliente,tVendedor
WHERE tDetallePedido.codiPedi= tPedido.codiPedi
AND tPedido.codiClien=tCliente.codiClien
AND tCliente.codiVende=tVendedor.codiVende;

Figura 5.16. Unir cuatro tablas en una consulta.

Preguntas y respuestas

 Pregunta: ¿Por qué la columna codiArti, que aparece en las tablas tArticulo y tDetallePedido,
no está calificada en la cláusula SELECT?
 Respuesta: Entre las tablas listadas en la consulta, sólo una de ellas contiene una columna
llamada codiArti, por tanto no es necesario calificar la tabla. Si la tabla tArticulo también
apareciera en la cláusula FROM, tendríamos que calificar codiArti para evitar confusiones
entre las columnas codiArti en las tablas tArticulo y tDetallePedido.

La consulta que vimos en la figura 5.16 es la más compleja de las que hemos examinado. Esto
podría hacerle pensar que, después de todo, SQL no es un lenguaje tan sencillo. Sin embargo, si
vamos paso a paso, la consulta del ejemplo 10 no es tan difícil. Para construir una consulta
detallada paso a paso, haga lo siguiente:

1. Liste en la cláusula SELECT todas las columnas que quiera mostrar. Si el nombre de una
columna aparece en más de una tabla, precédalo del nombre de la tabla (para calificar el
nombre de la columna).
2. Liste en la cláusula FROM todas las tablas que intervendrán en la consulta. Normalmente
se incluyen las tablas que contienen las columnas listadas en la cláusula SELECT. Sin
embargo, alguna vez puede haber una tabla que no contenga ninguna de las columnas
utilizadas en la cláusula SELECT pero que sí contiene columnas utilizadas en la cláusula

31
Asignatura: Sistemas de Base de Datos

WHERE. En este caso, también tenemos que listar la tabla en la cláusula FROM. Por
ejemplo, si no necesitamos listar el código y nombre del cliente, pero sí tenemos que
listar el nombre de vendedor, no incluiríamos ninguna columna de la tabla tCliente en la
cláusula SELECT. Sin embargo, la tabla tCliente sigue siendo necesaria, porque hay que
incluir una columna suya en la cláusula WHERE.
3. Tome un par de tabla relacionadas a la vez e indique en la cláusula WHERE la condición
que relaciona a las tablas. Una esas condiciones con el operador AND. Si hay alguna otra
condición, inclúyala en la cláusula WHERE y conéctelas con las otras condiciones con el
operador AND. Por ejemplo, si quiere ver artículos presentes en pedidos ordenados por
solo aquellos clientes con límites de crédito de 10000, tendría que añadir una condición
adicional a la cláusula WHERE, como vemos en la figura 5.17.

Figura 5.17. Restringir las filas al unir cuatro tablas.

Operaciones
En SQL podemos utilizar las operaciones para establecer la unión, intersección y diferencia de dos
tablas. La unión de dos tablas utiliza el operador UNION para crear una tabla temporal con todas
las filas que están en la primera tabla, en la segunda o en ambas. La intersección de dos tablas
utiliza el operador INTERSECT para crear una tabla temporal que contiene todas las filas que están
en ambas tablas. La diferencia de las dos tablas utiliza el operador MINUS para crear una tabla
temporal con el conjunto de todas las filas que están en la primera tabla pero que no están en la
segunda. Por ejemplo, imagina que TEMP1 es una tabla que contiene el código y nombre de cada
cliente representado por el vendedor 65, y que además TEMP2 es una tabla que contiene el
código y nombre de los clientes que tienen actualmente pedidos abiertos, como vemos en la
figura 5.18.

31
Asignatura: Sistemas de Base de Datos

Figura 5.18. Clientes del vendedor 65 y clientes con pedidos abiertos.

La unión de TEMP1 y TEMP2 (TEMP1 UNION TEMP2) consiste en el código y nombre de los
clientes representados por el vendedor 65 o bien que tienen actualmente pedidos abiertos, o
ambos. La intersección de estas dos tablas (TEMP1 INTERSECT TEMP2) contiene aquellos clientes
representados por el vendedor 65 y que tienen pedidos abiertos. La diferencia entre ambas tablas
(TEMP1 MINUS TEMP2) contiene aquellos clientes representados por el vendedor 65 pero que no
tienen pedidos abiertos. En la figura 5.19 vemos los resultados de este conjunto de operaciones.

Figura 5.19. Unión, intersección y diferencia entre las tablas TEMP1 y TEMP2.

Hay una restricción en las operaciones. Por ejemplo, no tiene sentido hablar de la unión de la
tabla tCliente y la tabla tPedido porque estas tablas no contienen las mismas columnas. ¿Cómo
serían las filas de la unión? Las dos tablas en la unión deben tener la misma estructura para que la
unión sea la adecuada, el término formal es “unión compatible”. Dos tablas son compatibles
cuando tienen el mismo número de columnas y sus correspondientes columnas tienen tipos de
datos y longitud idénticos.

Observe que la definición de unión compatible no especifica que las columnas de las dos tablas
deban ser idénticas, sino que las columnas deben ser del mismo tipo. Así, si una columna es
CHAR(20), la columna coincidente también debe ser CHAR(20).

Ejemplo 11
Liste el código y el nombre de los clientes que estén representados por el vendedor 65 o que
tengan actualmente pedidos abiertos, o ambos.

Podemos crear una tabla temporal que contenga el código y nombre de todos los clientes
representados por el vendedor 65 seleccionando los códigos y nombres de clientes de la tabla
tCliente para los que el código de vendedor sea 65.

Después podemos crear otra tabla temporal que contenga el código y nombre de los clientes que
tienen actualmente pedidos abiertos uniendo las tablas tCliente y tPedido. Las dos tablas

31
Asignatura: Sistemas de Base de Datos

temporales creadas en este proceso tienen la misma estructura, es decir, ambas contienen las
columnas codiClien y nombreClien. Como las tablas temporales son compatibles, es posible tomar
la unión de ambas tablas. En la figura 5.20 vemos la consulta y sus resultados.

Figura 5.20. Operador UNION.

Si la implantación de SQL utilizada tiene un buen soporte para la operación de unión, eliminará
automáticamente las filas duplicadas. Por ejemplo, los clientes que estén representados por el
vendedor 65 y que actualmente tengan pedidos abiertos aparecerá solo una vez en los resultados.
Oracle y SQL Server soportan la operación de unión y eliminan duplicados correctamente.

Ejemplo 12:
Liste el código y nombre de los clientes representados por el vendedor 65 y que actualmente
tengan pedidos abiertos.

La única diferencia entre esta consulta y la del ejemplo anterior es que el operador adecuado en
ésta es INTERSECT, como vemos en el ejemplo 5.21.

Figura 5.21. Operador INTERSECT.

31
Asignatura: Sistemas de Base de Datos

Algunas implantaciones de SQL no soportan en operador INTERSECT, por tanto tendríamos que
utilizar otro método. El comando de la figura 5.22 produce los mismos resultados que el operador
INTERSECT utilizando el operador IN y una subconsulta. El comando selecciona el código y nombre
de los clientes representados por el vendedor 65 y cuyo código de cliente también aparece en el
conjunto de códigos de cliente de la tabla tPedido.

Figura 5.22. Intersección sin utilizar el operador INTERSECT.

Ejemplo 13
Liste el código y el nombre de los clientes representados por el vendedor por el vendedor 65 pero
que actualmente no tengan pedidos abiertos.

La consulta utiliza el operador MINUS, como vemos en la figura 5.23. Al igual que con el operador
INTERSECT, algunas implantaciones de SQL no soporta el operador MINUS. En esos casos tenemos
que utilizar otro método, como el que vemos en la figura 5.24. Este comando produce los mismos
resultados seleccionando el código y nombre de los clientes representados por el vendedor 65 y
cuyo código de cliente no aparece en el conjunto de códigos de clientes en la tabla tPedido.

SELECT codiClien,nombreClien
FROM tCliente
WHERE codiVende='65'
AND codiClien NOT IN
(SELECT DISTINCT(tCliente.codiClien)
FROM tPedido,tCliente
WHERE tPedido.codiClien=tCliente.codiClien);

Figura 5.23. Operador MINUS.

31
Asignatura: Sistemas de Base de Datos

Figura 5.24. Llevar a cabo una diferencia sin utilizar el operador MINUS.

Nota: Oracle soporta el operador MINUS, pero SQL Server no.

ALL y ANY
Podemos utilizar los operadores ALL y ANY con subconsultas para producir una sola columna de
números. Cuando precedemos la subconsulta de un operador ALL, la condición será verdadera
sólo si cumple todos los valores que produce la subconsulta. Cuando precedemos la subconsulta
del operador ANY, la condición sólo es verdadera si cumple cualquier valor (uno o más) que
produzca la subconsulta. En los siguientes ejemplos veremos el uso de estos operadores.

Ejemplo 14
Busque el código, nombre, balance actual y código de vendedor de los clientes cuyos balances
excedan del balance máximo de todos los clientes representados por el vendedor 65.

Podemos encontrar el balance máximo de los clientes representados por el vendedor 65 en una
subconsulta y después encontrar los clientes cuyos balances son mayores que ese número. Sin
embargo, hay un método alternativo más sencillo. Podemos utilizar el operador ALL, como vemos
en la figura 5.25.

SELECT codiClien,nombreClien,balanClien,codiVende
FROM tCliente
WHERE balanClien>ALL
(SELECT balanClien
FROM tCliente
WHERE codiVende='65');

Figura 5.25. Comando SELECT que utiliza el operador ALL.

Para algunos usuarios la consulta que vemos en la figura 5.25 podría parecer más natural que
encontrar el balance máximo en la subconsulta, pero para otros puede ser lo contrario. Puede
utilizar el método que prefiera.

Preguntas y Respuestas
 Pregunta: ¿cómo podríamos obtener el mismo resultado del ejemplo 14 sin utilizar el
operador ALL?

31
Asignatura: Sistemas de Base de Datos

 Respuesta: Podemos seleccionar los clientes cuyo balance sea mayor que el balance máximo
de cualquier cliente del vendedor 65, como vemos en la figura 5.26.

SELECT codiClien,nombreClien,balanClien,codiVende
FROM tCliente
WHERE balanClien>
(SELECT MAX(balanClien)
FROM tCliente
WHERE codiVende='65');

Figura 5.26. Alternativa a utilizar el operador ALL.

Ejemplo 15
Busque el código, nombre, balance actual y código de vendedor de los clientes cuyo balance sea
mayor que el balance de al menos un cliente del vendedor 65.

Podemos encontrar el balance mínimo de los clientes representados por el vendedor 65 en una
subconsulta y después encontrar todos los clientes cuyo balance es mayor que ese número. Para
simplificar el proceso, podemos utilizar el operador ANY, como vemos en la figura 5.27.

Preguntas y Respuestas
 Pregunta: ¿Cómo podríamos obtener el mismo resultado utilizando el operador ANY?
 Respuesta: Podemos seleccionar los clientes cuyo balance sea mayor que el balance mínimo
de cualquier cliente del vendedor 65, como vemos en la figura 5.28.

31
Asignatura: Sistemas de Base de Datos

Figura 5.27. Comando SELECT con un operador ANY.

Figura 5.28. Alternativa a utilizar el operador ANY.

Operaciones Especiales
Podemos llevar a cabo operaciones especiales el SQL como la auto-unión que ya hemos utilizado.

Otras tres operaciones especiales son la unión interior, la unión exterior y el producto.

Unión Interior
Una unión interior es la que compara las tablas en una cláusula FROM y lista sólo las filas que
cumplen la condición en la cláusula WHERE. Las uniones que hemos llevado a cabo hasta ahora
eran uniones interiores. En el ejemplo 16 vemos la unión interior.

Ejemplo 16
Muestre el código de cliente, nombre de cliente, código de pedido y fecha de pedido de todos los
pedidos. Ordene los resultados por código de cliente.

31
Asignatura: Sistemas de Base de Datos

En este ejemplo necesitamos el mismo tipo de unión que hemos estado utilizando. El comando
es:

SELECT tCliente.codiClien, nombreClien, codiPedi, fechaPedi


FROM tCliente, tPedido
WHERE tCliente.codiClien = tPedido.codiClien
ORDER BY tCliente.codiClien;

El método anterior debería funcionar en cualquier implantación de SQL. Una actualización del
estándar SQL aprobado en 1992, llamado SQL-92, facilita una vía alternativa a llevar a cabo una
unión interior, como vemos en la figura 5.29.

Figura 5.29. Consulta que utiliza una cláusula INNER JOIN.

En la cláusula FROM liste la primera tabla y después incluya una cláusula INNER JOIN que incluya
el nombre de la segunda tabla. En lugar de una cláusula WHERE, utilice una cláusula ON que
contenga la misma condición que habría incluido en la cláusula WHERE.

Unión Exterior
En ocasiones es necesario listar todas las filas de una de las tablas en una unión,
independientemente de si coinciden o no con una fila de una segunda tabla. Por ejemplo,
podemos llevar a cabo la unión de las tablas tCliente y tPedido en la consulta del ejemplo 16, pero
mostrar todos los clientes, incluso los que no tienen pedidos. Este tipo de unión se denomina una
unión exterior. Hay tres tipos de uniones exteriores. En una unión exterior izquierda se incluyen
todas las filas de la tabla de la izquierda (la tabla listada en primer lugar en la consulta),
independientemente de si coinciden o no con alguna fila de la tabla de la derecha (la tabla listada
en segundo lugar en la consulta). Las filas de la tabla de la derecha se incluyen sólo cuando
coinciden. En una unión exterior derecha se incluyen todas las filas de la tabla de la derecha,
independientemente de si coinciden o no con filas de la tabla de la izquierda. Las filas de la tabla
de la izquierda sólo se incluyen cuando coinciden. En una unión exterior completa se incluyen
todas las filas de ambas tablas, independientemente de si coinciden o no con filas de la otra tabla.
(La unión exterior completa apenas se utiliza.) En el ejemplo 17 vemos el uso de una unión
exterior izquierda.

31
Asignatura: Sistemas de Base de Datos

Ejemplo 17
Muestre el código de cliente, nombre de cliente, código de pedido y fecha de pedido de todos los
pedidos. Incluya todos los clientes en los resultados. Para los clientes que no tienen pedidos,
omita el código de pedido y la fecha de pedido.

Figura 5.30. Consulta que utiliza una cláusula LEFT JOIN

Para incluir a todos los clientes, hay que llevar a cabo una unión exterior. Asumiendo que la tabla
tCliente se lista en primer lugar, la unión debería ser una unión exterior izquierda. En SQL,
utilizamos la cláusula LEFT JOIN para llevar a cabo una unión exterior izquierda, como vemos en la
figura 5.30. (Deberíamos utilizar una cláusula RIGHT JOIN para llevar a cabo una unión exterior
derecha.) Todos los clientes se incluyen en los resultados. Los clientes que no tienen pedidos, el
código de pedido y la fecha aparecen en blanco. Técnicamente, esos valores en blanco son nulos.

Nota: En Oracle, hay otra manera de llevar a cabo uniones exteriores izquierda y derecha.
Escribimos la unión como hemos hecho hasta ahora, con una excepción. Incluimos paréntesis y un
signo más en la cláusula WHERE después de la columna de la tabla en la que se incluyen solo filas
coincidentes. En este ejemplo, el signo más seguirá a la columna codiClien de la tabla tPedido
porque sólo se pueden incluir los pedidos que coinciden con los clientes. Como los clientes que no
tienen pedidos se incluirán en los resultados, no habría signo más después de la columna
codiClien en la tabla tCliente. La consulta correcta sería así:
SELECT tCliente.codiClien, nombreClien, codiPedi, fechaPedi
FROM tCliente, tPedido
WHERE tCliente.codiClien = tPedido.codiClien (+)
ORDER BY tCliente.codiClien;

31
Asignatura: Sistemas de Base de Datos

Al ejecutar esta consulta obtendremos los mismos resultados de la figura 5.30.

Producto
El producto (formalmente llamado producto cartesiano) de dos tablas es la combinación de todas
las filas de la primera tabla y todas las filas de la segunda tabla.

Nota: La operación producto no es habitual. Sin embargo, es necesario conocerla, porque es fácil
crear un producto inadvertidamente omitiendo la cláusula WHERE cuando intentamos unir tablas.

Ejemplo 18
Forme el producto de las tablas tCliente y tPedido. Muestre el código de cliente y el nombre a
partir de la tabla tCliente, junto con el código de pedido y la fecha de pedido de la tabla tPedido.

Formar un producto es realmente muy sencillo. Simplemente omitimos la cláusula WHERE, como
vemos en la figura 5.31.

Figura 5.31. Consulta que produce un producto de dos tablas.

Pregunta y Respuestas
 Pregunta: La figura 5.31 no muestra todas las filas del resultado. ¿Cuántas filas están
realmente incluidas?
 Respuesta: La tabla tCliente tiene 10 filas y la tabla tPedido tiene 7 filas. Como cada una de las
10 filas de cliente coincide con cada una de las siete filas de pedido, hay (10*7) filas en el
resultado.

31
Asignatura: Sistemas de Base de Datos

31

También podría gustarte