Está en la página 1de 36

UT_4 GBD

UT_4 Realizacin de consultas.


En esta unidad aprenderemos a extraer la informacin de una base de datos estableciendo los
requisitos y criterios para seleccionar los datos.
Por lo que has estudiado en unidades anteriores, conoces las ventajas que ofrece un SGBD,
pero tambin sabes que si no conocemos la forma de relacionarnos con la base de datos, la
informacin puede estar disponible pero no podremos acceder a ella.
El SGBD va a ser capaz, a partir de las sentencias, de hacer consultas enlazando las tablas
mediante las relaciones definidas en el diseo y en la creacin. Por eso es tan importante que
todo se haya hecho respetando los criterios establecidos por el modelo, tanto en la fase de
diseo lgico como fsico. De no hacerlo as nos podramos encontrar con que, una vez realizado
todo el trabajo y despus de registrar los datos en las tablas, no tenemos acceso a lo que
buscamos, o que la informacin devuelta por las consultas resulta incoherente.

1.- Herramientas para la realizacin de consultas.


Como sabemos un SGBD integra, adems de la base de datos, un conjunto de herramientas
que nos facilitan el diseo, la gestin y la administracin de la base de datos.
En unidades anteriores hemos visto cmo algunas de esas herramientas nos pueden ayudar a
establecer tanto el diseo lgico como el diseo fsico de la base de datos. En el caso del diseo de
consultas tambin contamos cada vez con un mayor nmero de utilidades.
Podemos hacer una clasificacin de estas herramientas en dos tipos:

Herramientas proporcionadas por el SGBD: algunos gestores proporcionan un entorno


integrado donde se incluyen asistentes, editores grficos, etc. En esta categora nos
encontramos con Microsoft Access, OpenOffice Base, Workbench o phpMyAdmin. Las dos
ltimas se utilizan, exclusivamente, para interactuar con servidores MySQL.
Herramientas externas al gestor: en este caso hablamos de herramientas que aaden
funcionalidades y son compatibles con distintas bases de datos. Navicat y HeidiSQL
pertenecen a este tipo de herramientas.

Durante el presente tema utilizaremos algunas de las herramientas que hemos citado, teniendo en
cuenta que se trata solo de algunas de las numerosas herramientas presentes en el mercado, tanto
de software libre como propietario.

1.1- Asistentes y herramientas grficas de diseo de


consultas.
Tanto incluidos en el propio SGBD, como cuando se trata de aplicaciones externas al propio gestor,
existen herramientas grficas que nos ayudan a realizar consultas a una o ms tablas de una
base de datos de una forma fcil y sencilla, incluso sin necesidad de conocer el lenguaje SQL.
Podemos clasificar esas herramientas en:

Asistentes para consultas.


Herramientas para el diseo consultas.
Creacin de consultas desde un asistente para consultas:
Estos asistentes son aplicaciones que nos permiten seleccionar las tablas, los campos, el
orden de las filas, establecer criterios de seleccin, grupos y clculos, etc., siguiendo
unos pasos muy sencillos.

UT_4 GBD
Ejemplos de estos asistentes los podemos ver en OpenOffice Base y en Microsoft Access,
aunque tambin incorporan este tipo de asistentes bases de datos como Oracle.
Creacin de consultas desde la ventana de diseo de consultas:
Tanto en los propios SGBD como en aplicaciones que se pueden instalar para aumentar las
prestaciones y que son externas al SGBD, podemos encontrar herramientas grficas para
disear consultas mediante opciones como:

Representaciones grficas de tablas y campos.


Opciones con listas desplegables para elegir los tipos de datos, los tipos de ndices, etc.
Posibilidad de establecer los criterios de seleccin, de ordenacin, etc, seleccionando
opciones o eligiendo operadores, etc.

Se trata de herramientas que permiten al usuario elaborar consultas sencillas de forma


intuitiva, con el simple manejo de recursos grficos presentados en una ventana donde se
encuentran disponibles todos los elementos que representan las distintas clusulas que una
consulta puede recoger. Aplicaciones como Workbench, phpMyAdmin o Navicat incorporan
este tipo de herramientas.
Recomendacin
Accede a la pgina oficial de Navicat y comprueba qu aplicaciones ofrece para la gestin de
servidores de bases de datos.
Descarga la aplicacin Navicat for MySQL (versin de prueba de 30 das). Instlala en tu
ordenador, ejectala, y recorre las principales opciones. Ms adelante usaremos Navicat en algunos
ejercicios.
Tambin es interesante que te descargues el manual oficial de la aplicacin, en formato pdf (est en
ingls).

1.2.- Editores de SQL.


Aunque hemos citado una serie de herramientas que nos pueden facilitar el diseo de consultas, la
herramienta ms potente a la hora de establecer criterios para seleccionar la informacin
almacenada en una base de datos, es el lenguaje SQL.
Todos los SGBD tienen un editor que, con ms o menos elementos de ayuda, nos permite introducir
nuestras instrucciones y nos muestra dnde se producen los posibles errores.

2.- El lenguaje de manipulacin de datos: LMD.


En la unidad anterior clasificamos las sentencias del lenguaje SQL en 3 tipos recuerdas?
Lenguaje SQL
LDD
(Lenguaje de Definicin de Datos)
LMD
(Lenguaje de Manipulacin de Datos)
LCD
(Lenguaje de Control de Datos)

Sentencias
Incluye sentencias para gestionar las estructuras.
Incluye sentencias para gestionar los datos.
Incluye sentencias para gestionar la seguridad y los permisos.

UT_4 GBD
Pues bien, ahora vamos a tratar con el LMD, que es una parte del lenguaje SQL que se encarga de
la gestin de los datos almacenados. El LMD tiene instrucciones para ayudarnos a:

Insertar filas (INSERT).


Consultar los datos almacenados (SELECT).
Modificar esos datos (UPDATE).
Borrar filas (DELETE).
En esta unidad nos centraremos en la sentencia SELECT, en unidades posteriores se estudiarn el
resto de sentencias.
Sin ninguna duda, la operacin que ms veces se realiza sobre una base de datos es la
consulta.

3.- Sentencias para crear consultas: SELECT.


Como hemos visto, las herramientas grficas nos ofrecen una gran ayuda a la hora de enviar
consultas a nuestra base de datos. Pero sin duda, para tener mayor control sobre cualquier SGBD,
y en concreto sobre las consultas a los datos que almacena, Alejandra piensa que lo ms seguro
es conocer las instrucciones de SQL que integran el LMD.
Para realizar consultas se utiliza la sentencia SELECT. Siguiendo el criterio de Alejandra,
aprenderemos a utilizar las opciones ms importantes de SELECT, desde consultas sencillas sobre
una sola tabla, hasta consultas complejas combinando datos de varias tablas, conocidas como
consultas multitabla.
SELECT es la sentencia que tiene mayores variaciones y opciones sintcticas en todos los
SGBD del mercado, y tambin la ms compleja y potente de todas las instrucciones SQL.
Utilizaremos esta sentencia para consultar los datos de una base de datos. En la sentencia
SELECT el usuario especifica lo que quiere obtener, no cmo, ni dnde.
Como hemos dicho presenta muchas opciones. Las ms comunes son:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
{Expresin | Columna1, ... | * }
FROM TablasReferenciadas
[WHERE Condiciones]
[GROUP BY {NombreColumna | Expresin | Posicin} [ASC | DESC], ]
[HAVING Condiciones]
[ORDER BY { NombreColumna | Expresin | Posicin } [ASC | DESC] , ...]
[LIMIT { [desplazamiento,] contador | contador OFFSET desplazamiento} ]
Antes de empezar a analizar la funcin de cada una de las clusulas de esta sentencia, veremos
algunas consideraciones generales:

Para realizar una consulta a una o varias tablas con esta sentencia, es imprescindible utilizar

al menos las palabras:


o SELECT seguido del nombre de la columna o columnas que se quieran mostrar.
o FROM seguido del nombre de la tabla o tablas de las que se obtienen los datos.
El resto de las clusulas son opcionales, pero en el caso de que se incluyan debe respetarse
el orden descrito.
La sentencia SELECT no se limita a nombres de columnas de tablas o a un *, pueden ser
otras expresiones, funciones, etc.; incluso aunque no correspondan a ninguna tabla. Un
ejemplo se muestra a continuacin:
SELECT 7*4, SIN(3.1414/2), CURRENT_DATE();

Tambin es vlido, y adems necesario cuando se seleccionan varias columnas con el mismo
nombre en diferentes tablas, especificar el nombre de la columna separado con un punto
del nombre de la tabla. Un ejemplo se muestra a continuacin:

UT_4 GBD
SELECT CLIENTES.Nombre, CLIENTES.Apellidos FROM CLIENTES;

Se pueden consultar datos de tablas de una base de datos que no est actualmente en uso,
escribiendo el nombre de la base de datos a la que pertenece, separado con un punto del
nombre de la tabla, como se muestra a continuacin:
SELECT * FROM TalleresFaber.CLIENTES;

3.1.- Clusulas de SELECT I.


Como hemos visto, el formato bsico de esta sentencia incluye, como mnimo, la palabra SELECT
y la clusula FROM. Empezaremos por describir su sintaxis y seguiremos con el resto de las
clusulas que ms se utilizan.
Detrs de la palabra SELECT se especificar la lista de seleccin, es decir, la lista de campos o
expresiones que se quieren mostrar en el resultado de la consulta. Los nombres de las columnas o
expresiones que se incluyan en la lista de seleccin se escriben separados por comas.
En la lista de seleccin se puede escribir un *, para indicar que se quieren obtener los datos de
todos los campos de la tabla o tablas.
La clusula FROM permite indicar la tabla o tablas que contienen los datos que se quieren
consultar.
El encabezado de las columnas que aparece en el resultado de las consultas, es el nombre de la
columna o campo correspondiente. Si ste resulta demasiado largo o es el resultado de un clculo,
se puede cambiar usando un alias de columna. Es posible asignar un alias a cualquiera de las
expresiones de la lista de seleccin del SELECT. Para ello, se escribe tras el nombre de columna la
clusula AS seguida del nuevo nombre que va a aparecer en el encabezado entre comillas, aunque
esta palabra es opcional.
El alias puede usarse dentro de toda la consulta, en cualquier referencia a la columna
correspondiente, por ejemplo, dentro de las clusulas WHERE, HAVING o GROUP BY que
veremos ms adelante.
A continuacin se asigna un alias al campo CodCliente de una tabla.
SELECT CodCliente AS Cdigo de cliente, Apellidos, Nombre FROM CLIENTES;
Un alias se puede utilizar tambin para asociar un nuevo nombre a una tabla. Se trata de un
nombre, generalmente ms corto, que se utiliza sobre todo cuando consultamos varias tablas y hay
nombres de columnas que coinciden. En este caso se conoce como alias de tabla.
En el siguiente ejemplo hemos asignado el alias E a la tabla EMPLEADOS, y el alias C a la tabla
CLIENTES, por eso los nombres de las columnas van precedidos del alias E C seguido de un
punto.
SELECT E.Apellidos, E.Nombre, C.Apellidos, C.Nombre FROM EMPLEADOS E, CLIENTES C WHERE ;
Una consulta en SQL puede incluir columnas cuyos valores se obtienen haciendo clculos a partir
de los datos almacenados en las columnas de las tablas. A estas columnas se conocen como
columnas calculadas. Cuando queremos mostrar el resultado de la columna calculada dentro de
SELECT, es conveniente utilizar un alias de columna para evitar que se incluya como cabecera la
propia funcin u operacin realizada.
El siguiente ejemplo muestra cmo puede asignarse un alias de columna a una columna calculada:
SELECT IdReparacin, (FechaSalida FechaEntrada) AS Das empleados FROM REPARACIONES;

UT_4 GBD
La clusula WHERE permite obtener los datos de las filas que cumplen con la condicin expresada.
Tras WHERE se escribe una expresin de tipo relacional o de comparacin, que usar alguno de
los operadores relacionales y lgicos que veremos en apartados posteriores.
El formato de la condicin es: expresin operador expresin
Pueden construirse condiciones mltiples con los operadores lgicos AND, OR o NOT.
En una clusula WHERE se puede usar cualquier funcin disponible en el SGBD que se est
usando, excluyendo slo las de resumen. Estas ltimas funciones estn diseadas especficamente
para usarse en clusulas GROUP BY y se vern en otro apartado.
El siguiente ejemplo muestra una consulta que incluye una condicin en la clusula WHERE:
SELECT Matricula FROM VEHICULOS WHERE color=azul OR marca=SEAT;
A lo largo de este tema realizaremos numerosos ejercicios para aprender a manejar el
lenguaje SQL. Como base de la mayora de los ejercicios usaremos la base de datos
bdempleados, que se crear en un servidor MySQL. En el siguiente ejercicio crearemos
dicha base de datos, e insertaremos algunos datos en sus tablas.
Ejercicio: Creacin de la base de datos bdempleados.
Utiliza el cliente grfico Navicat para crear la base de datos bdempleados en tu servidor MySQL.
Abajo se describe la estructura y contenido de las tablas que componen dicha base de datos, as
como las relaciones que existen entre las distintas tablas. Obsrvese que se ha duplicado la tabla
empleados para poder representar la interrelacin reflexiva sobre s misma, pero solo hay que crear
una tabla de empleados. Cada campo se definir del tipo ms apropiado para albergar los datos
que contendr. Recuerda que es muy importante definir el tipo de los campos que actan de clave
fornea, del mismo tipo con el que se defina la clave primaria a la que hacen referencia.

Tabla: empleados
Clave primaria: numemp
Claves forneas:
oficina->referencia a oficinas.oficina
jefe->referencia a empleados.numemp

UT_4 GBD

Tabla: oficinas
Clave primaria: oficina
Claves forneas:
dir->referencia a empleados.numemp

Tabla: clientes
Clave primaria: numclie
Claves forneas:
repclie->referencia a empleados.numemp

UT_4 GBD
Tabla: productos
Clave primaria: idproducto

Tabla: pedidos
Clave primaria: codigo
Claves forneas:
clie->referencia a clientes.numclie
rep->referencia a empleados.numemp
producto->referencia a productos.idproducto

UT_4 GBD

Recomendacin
Todas las consultas que se piden en los ejercicios deben probarse sobre el servidor MySQL.
Puedes escribir las consultas en la lnea de comandos o en cualquier cliente grfico de MySQL.
Es muy importante que se almacenen todas las sentencias que se realicen en los distintos
ejercicios. Para ello puedes utilizar cualquier editor de texto plano.
Ejercicio: Alias de columna.
Realiza las siguientes consultas en SQL sobre la BD bdempleados:

Seleccionar el nombre de todos los empleados, haciendo que aparezca como ttulo de la
columna Nombre de empleado.

Seleccionar el nmero de oficina, con encabezado Nmero de oficina, la ciudad, con


encabezado Ciudad de destino y la regin, de todas las oficinas cuyo objetivo de venta
sea menor de 400000.

Ejercicio: Columnas calculadas.


Realiza las siguientes consultas en SQL sobre la BD bdempleados:

Seleccionar el nombre de cada empleado y la mitad de su cuota. El encabezado de la mitad

de su cuota ser Mitad de la cuota. Slo aparecern los datos de los empleados para los
cuales el doble de sus ventas sea mayor que 650000 y menor que 800000.
Seleccionar el nombre de cada empleado y el nmero de aos que le restan para jubilarse,
encabezando estos valores con el ttulo Aos restantes de trabajo. Slo se incluirn en el
resultado de la consulta aquellos empleados mayores de 40 aos y cuyo contrato fuese
formalizado antes de octubre del 88.
Seleccionar el nombre de la ciudad, el cdigo del director de la oficina y la mitad de la
diferencia entre ventas y objetivo, de todas las oficinas para las que el 30% de las ventas
sea mayor que el 15% del objetivo. El formato de la salida ser:
Ciudad oficina: ciudad Cdigo director: dir Mitad diferencia: resultado
Nota: Condiciones para fechas -> WHERE
MONTH(fecha)=12 AND YEAR(fecha)<2014

fecha

<

"12/3/2014"

----

WHERE

UT_4 GBD

3.2.- Clusulas de SELECT II.


La clusula ORDER BY permite obtener los datos ordenados ascendente o descendentemente
con relacin a una o varias columnas. Se puede elegir el orden ascendente o descendente
aadiendo a continuacin ASC o DESC. Por defecto se usa el orden ASC.
A continuacin se obtiene un listado con la marca y el modelo de los vehculos que se reparan en
nuestro taller, ordenado alfabticamente por marca y, en caso de coincidencia, ordenado
ascendentemente por modelo:
SELECT Marca, Modelo FROM VEHICULOS ORDER BY Marca ASC, Modelo ASC;
La clusula ALL permite que se puedan presentar todas las filas afectadas por el resto de
condiciones de la consulta aunque algunas estn repetidas. Es la opcin por defecto.
El siguiente ejemplo muestra un listado de las matrculas de los vehculos que han sufrido
reparaciones. Si el vehculo se ha reparado ms de una vez, su matrcula aparecer repetida.
SELECT ALL Matricula FROM REPARACIONES;
Por el contrario, la clusula DISTINCT se usan cuando no queremos que se presenten en el
resultado filas repetidas.
A continuacin se muestra un listado de las matrculas de los vehculos que han sufrido
reparaciones. En este caso, si el vehculo se ha reparado ms de una vez, evitaremos que su
matrcula aparezca repetida.
SELECT DISTINCT Matricula FROM REPARACIONES;
Es posible agrupar las filas que devuelve una consulta segn los valores de una columna usando la
clusula GROUP BY. Estas consultas se denominan consultas agrupadas y las veremos en esta
unidad.
En las consultas de agrupadas se suelen usar funciones de resumen o reunin, tambin
conocidas como funciones de columna. Por ejemplo: COUNT(), SUM(), MAX(), MIN(), AVG(),
STD(), VARIANCE(), etc.
Estas funciones tambin se pueden usar sin la clusula GROUP BY siempre que en la consulta no
se seleccionen otras columnas. En este caso se denominan consultas de resumen.
La clusula HAVING suele utilizarse en combinacin con la clusula GROUP BY, y es parecida a la
clusula WHERE. En concreto, permite hacer selecciones en situaciones en las que no es posible
usar WHERE. La clusula WHERE no se puede aplicar a columnas calculadas mediante las
funciones de reunin que hemos mencionado en el apartado anterior. Tanto la clusula GROUP BY
como HAVING se tratarn ms adelante en el apartado de consultas agrupadas.
La clusula LIMIT permite limitar el nmero de filas devueltas por una consulta. Se suele utilizar
para no sobrecargar demasiado al servidor o a la aplicacin que va a recibir los resultados de la
consulta.
LIMIT puede admitir uno o dos parmetros:

Cuando se usa un solo valor indica el nmero de filas devueltas.


Cuando se usan dos valores, el primero indica el nmero de la primera fila y el segundo el
nmero de filas a recuperar. Si el segundo argumento es -1, entonces se devolvern todas
las filas hasta la ltima.

A continuacin pueden verse varios ejemplos del uso de LIMIT:


mysql> SELECT * FROM table LIMIT 5,10; # Devuelve las filas 6-15

UT_4 GBD
Nota: empieza a contar desde cero, es decir, la fila 5 es la sexta.
mysql> SELECT * FROM table LIMIT 95,-1; # Devuelve las filas 96-ltima.
mysql> SELECT * FROM table LIMIT 5; # Devuelve las 5 primeras filas.<br />
Ejercicio resuelto
Queremos consultar la referencia, descripcin e importe de las 10 actuaciones ms baratas
que se pueden llevar a cabo en nuestro taller.
SELECT Referencia, Descripcion, Importe FROM ACTUACIONES ORDER BY Importe LIMIT 10;
Solution:
SELECT Referencia, Descripcion, Importe FROM ACTUACIONES ORDER BY Importe LIMIT 10;
Ejercicio: ORDER BY.
Realiza las siguientes consultas en SQL sobre la BD bdempleados:

Seleccionar la primera, tercera y ltima columna de la tabla empleados. Aparecern todos los
registros ordenados descendentemente por la tercera columna.

Seleccionar el nombre y la edad de todos los empleados cuya edad est comprendida

estrictamente entre 45 y 65. El encabezado de la primera columna ser Empleados


mayores. Los nombres aparecern ordenados por la edad.
Seleccionar la regin y la ciudad de todas las oficinas que no estn en el norte ni tengan
menos de 300000 euros de objetivo de ventas. El resultado aparecer ordenado
ascendentemente por regin, y descendentemente por ciudad.
Seleccionar el nombre de empleado y el 25% de sus ventas. Este ltimo dato aparecer con
el encabezado Beneficios de empleado. No se incluirn en el resultado de la consulta
aquellos empleados cuyo beneficio no sea superior a 80000. El resultado aparecer
ordenado por beneficios, ascendentemente.
Ejercicio: ALL, DISTINCT, LIMIT
Realiza las siguientes consultas en SQL sobre la tabla pedidos de la BD bdempleados:

Seleccionar los aos en que se realizaron algn pedido (sin repeticiones). Los aos
aparecern ordenados cronolgicamente, de mayor a menor.

Selecciona los registros del 2 al 5 de la tabla pedidos.


Selecciona los tres primeros registros de la tabla pedidos.
Selecciona el tercer registro de la tabla pedidos.

4.- Operadores.
Una vez vistas las clusulas que pueden intervenir en una consulta, Alejandra considera
importante conocer tambin los operadores que se pueden usar dentro de las expresiones
en el SGBD que est utilizando, en este caso MySQL, y que le ayudarn, entre otras cosas, a
establecer condiciones de bsqueda bsicas.
Aunque ya hemos usado algunos operadores que pueden intervenir en una sentencia SQL, dado
que en la mayor parte de los casos se incluyen en sentencias de tipo SELECT, vamos a ampliar en
este apartado los tipos de operadores.
Con el lenguaje SQL podemos utilizar muchos operadores diferentes para cada tipo de
columna. Veremos los operadores de que dispone MySQL, pero la mayora de ellos son
compatibles con otros SGBD.
Los operadores se utilizan para construir expresiones que se usan en clusulas WHERE,
ORDER BY y HAVING y adems se pueden emplear directamente en las sentencias.

10

UT_4 GBD
Los operadores sirven para construir expresiones. Se pueden utilizar con nmeros, cadenas de
caracteres, fechas, campos booleanos, binarios, etc.
Una expresin es una combinacin de operadores y operandos (como campos, constantes,
variables, funciones y otras expresiones) que se combinan unos con otros.
En el siguiente ejemplo hemos consultado los datos apellidos, nombre y direccin de los empleados
de Talleres Faber que viven en Cantabria. Se establece como condicin que los dos primeros
caracteres del cdigo postal sean 39. (No te preocupes por el operador LIKE, se ver en otro
apartado ms adelante)
SELECT Apellidos, Nombre, Direccin FROM EMPLEADOS WHERE CP LIKE 39%;
Si en una expresin aparecen varios operadores, se evalan en un orden determinado. Los
operadores de mayor prevalencia se evalan primero y as hasta los de menor prevalencia. Cuando
dos o ms operadores tienen igual prevalencia, se evalan de izquierda a derecha. En una
expresin en la que se utilicen parntesis para agrupar parte de los elementos de la expresin, se
evalan primero los parntesis ms internos y con lo que se obtiene se van evaluando los
parntesis siguientes hasta los ms externos.
Los parntesis tienen mayor prevalencia que cualquier operador.
Debes conocer
Para consultar el orden de prioridad de los operadores disponibles en MySQL pincha en el siguiente
enlace:
Orden de prioridad de los operadores: http://dev.mysql.com/doc/refman/5.6/en/operatorprecedence.html.
Reflexiona
En caso de que tengas que combinar varios operadores en una misma expresin, es aconsejable
que utilices tantos parntesis como consideres necesario para que stos se evalen en el orden
que te interese. De este modo evitars sorpresas desagradables.

4.1.- Operador de asignacin y Operadores


aritmticos.
Operador de asignacin:
En MySQL podemos crear variables y usarlas posteriormente en expresiones. Podemos crear
variables de dos formas:

Con SET. Por ejemplo:


SET @hoy= CURRENT_DATE();
SELECT @hoy;
(Veremos la fecha actual)

Utilizando el operador de asignacin :=. Por ejemplo:


SELECT @X:=10;
SELECT @X;
(Veremos el valor almacenado 10)

Una variable sin asignar ser de tipo cadena y su valor ser NULL.

11

UT_4 GBD
Operadores aritmticos:
Los operadores aritmticos se aplican a valores numricos, ya sean enteros o en coma flotante. El
resultado
siempre
es
un
valor
numrico,
entero
o
en
coma
flotante.
MySQL dispone de los operadores aritmticos habituales: suma, resta, multiplicacin, divisin,
potencia, etc.
Operador

Significado

Se utiliza para sumar dos nmeros y, como operador unario, para simbolizar signo positivo
de un nmero.

Se utiliza para hallar la diferencia entre dos nmeros y, como operador unario, para
simbolizar signo negativo de un nmero.

Se utiliza para multiplicar dos nmeros.

Se utiliza para dividir dos nmeros.

Se utiliza para elevar un nmero a la potencia del exponente (nmero ^ exponente).

Se utiliza para dividir dos nmeros y el resultado cociente en forma de entero (divisin
entera) entero.

% o mod

Dividen dos nmeros y devuelven el resto entero de la divisin.

Se obtiene un valor de signo contrario.

Los operadores de mayor prevalencia son los aritmticos, y entre ellos, el orden de prevalencia es:
1.
2.
3.
4.

Exponenciacin.
Operadores de signo.
Multiplicacin y divisin.
Suma y resta.

4.2.- Operadores de comparacin.


Para crear expresiones lgicas disponemos de los operadores de comparacin que se aplican a
cualquier tipo de columna: cadenas, nmeros, fechas, etc. Estos operadores devuelven los valores
lgicos de verdadero o falso. (1 0).
Estos operadores son habituales en cualquier lenguaje de programacin, pero algunos lenguajes
como MySQL aade algunos muy tiles que se usan frecuentemente.
Operador

Significado

<=

Menor o igual.

<

Menor.

>

Mayor.

>=

Mayor o igual

Compara dos expresiones y devuelve 1, sin son iguales y 0, si son diferentes.

12

UT_4 GBD

<=>

Funciona como =, salvo que si una de las dos expresiones o las dos es nula, el resultado no
es NULL. Si se comparan dos expresiones nulas, el resultado es verdadero (1).
Si solo una de las dos expresiones es nula, entonces el resultado es falso (0).

< > !=

Si las expresiones comparadas son diferentes, el resultado es verdadero, y si son iguales, el


resultado es falso.

Estos operadores tienen todos ellos la misma prioridad.


Comparacin de cadenas de caracteres y de fechas:
Los operadores relacionales pueden usarse para comparar cadenas.

Cuando se comparan cadenas, se considera menor la cadena que aparezca antes por orden
alfabtico no distinguiendo entre maysculas y minsculas, a no ser que se realicen sobre
campos definidos con el atributo BINARY.
Las cadenas constantes se han de expresar encerradas entre comillas dobles o simples.
Si son fechas, se considera menor cunto ms antigua sea.

4.3.- Operadores lgicos.


Los
operadores
lgicos
se
usan
para
crear
expresiones
lgicas
complejas.
Solo existen dos valores posibles para los resultados: verdadero y falso, pero MySQL aade un
tercer valor: desconocido para poder trabajar con valores NULL.
1

TRUE

FALSE

desconocido

NULL

Operador

Funcin

AND &&

Devuelve el valor TRUE cuando las dos condiciones son verdaderas y FALSE si alguna
de ellas es falsa.

OR ||

Devuelve el valor TRUE si cualquiera de las dos condiciones es verdadera y FALSE


cuando las dos condiciones son falsas

NOT !

Devuelve lo opuesto a la condicin que sigue a NOT. Si el operador es NULL devuelve


NULL.

XOR

Devuelve NULL si cualquiera de los operadores es NULL. Cuando uno de los operadores
es verdadero, devuelve TRUE y si ambos son verdaderos o falsos devuelve FALSE.

Todos estos operadores tienen menor prevalencia en las expresiones que los operadores
aritmticos. Entre ellos, el orden de prevalencia es el siguiente:
1.
2.
3.
4.

Operadores de comparacin
Operador NOT
Operador AND
Operador OR

Al igual que todos los operadores binarios que veremos, los operadores AND y OR se pueden
asociar, es decir, se pueden crear expresiones como

13

UT_4 GBD
A AND B AND C.
El hecho de que se requieran dos operandos significa que las operaciones se realizan tomando los
operandos dos a dos, y estas expresiones se evalan de izquierda a derecha. Primero se evala A
AND B, y el resultado, R, se usa como primer operando de la siguiente operacin R AND C.
Ejercicio resuelto
Consultar las matrculas de los vehculos que hayan entrado a reparar en 2014 con menos de
100000 Km, y que hayan salido del taller sin reparar:
SELECT IdReparacion, Matricula FROM REPARACIONES WHERE
(FechaEntrada>=2014-01-01 AND km<100000)
AND Reparado=False;
Solution:
SELECT IdReparacion, Matricula FROM REPARACIONES WHERE
(FechaEntrada>=2014-01-01 AND km<100000)
AND Reparado=False;

4.4.- Operadores especiales.


En MySQL disponemos de los operadores LIKE y NOT LIKE para comparacin de cadenas, y que
se utilizan para construir las condiciones de WHERE y HAVING.
Tanto si la cadena como el patrn son NULL, el resultado es NULL. LIKE no distingue entre
maysculas y minsculas, a no ser que en la comparacin se vea involucrado un campo definido
como BINARY.
La sintaxis de LIKE es:
Expresin [NOT] LIKE patrn
En SQL de MySQL tenemos dos caracteres especiales que pueden aparecer en cualquier posicin
del patrn:
Comodn

Significado

Representa a cualquier cadena de 0 o ms caracteres.

Representa a un carcter cualquiera.

Por ejemplo, para obtener los nombres y apellidos de los clientes cuyo primer apellido comience por
la letra M haramos lo siguiente:
SELECT Nombre, Apellidos FROM CLIENTES WHERE Apellidos LIKE M%;
Y para obtener los nombres y apellidos de los clientes cuyo apellido no sea Snchez escribiramos:
SELECT Nombre, Apellidos FROM CLIENTES WHERE Apellidos NOT LIKE %Snchez%;

Otros operadores especiales son BETWEEN y NOT BETWEEN, que sirven para comprobar si una
expresin est comprendida en un determinado rango de valores. Su sintaxis es:
Expresin [NOT] BETWEEN ValorInicial AND ValorFinal

14

UT_4 GBD
Por ejemplo, para obtener un listado con los nmeros de referencia y la descripcin de las
actuaciones cuyo tiempo estimado de realizacin est entre 30 y 60 minutos, podramos escribir
cualquiera de las dos siguientes consultas:
SELECT Referencia, Descripcion FROM ACTUACIONES WHERE TiempoEstimado BETWEEN 0.30 AND 0.60;

SELECT Referencia, Descripcion FROM ACTUACIONES WHERE TiempoEstimado >=0.30 AND TiempoEstimado
<= 0.60;
Reflexiona
Observa la diferencia entre las dos soluciones del ejemplo anterior:

Con BETWEEN la expresin que se evala se escribe una sola vez.


En el segundo ejemplo las expresiones a ambos lados de AND deben escribirse completas.
Los ltimos operadores especiales que comentaremos en este apartado son IN y NOT IN. El
operador IN devuelve 1 (verdadero) si el valor de una expresin es igual a alguno de los valores de
una lista, y falso en caso contrario. El operador NOT IN devuelve 1 (verdadero) si el valor de la
expresin no est en la lista. Su sintaxis se indica a continuacin:
Expresin IN [NOT IN] (Valor1, Valor2, . )
Podramos obtener un listado de matrculas de los vehculos que hemos registrado de las marcas:
Seat, Ford o Peugeot, mediante la siguiente consulta:
SELECT Matricula FROM VEHICULOS WHERE Marca IN (Seat, Ford, Peugeot);
Reflexiona
Cmo buscaramos en una cadena el carcter % el _?
Para poder buscar un carcter % _ como carcter dentro de una cadena, ste deber ir
precedido de un carcter de escape, que es la barra invertida o contrabarra.
Ejemplo: Queremos ver el Nombre de una serie de artculos que en la columna IVA contienen el
smbolo % al final.
SELECT Nombre FROM ARTICULOS WHERE IVA LIKE %\%;
Del carcter de escape se habl en el recurso: Reglas para escribir sentencias SQL de la
unidad anterior.

Retroalimentacin:
Para poder buscar un carcter % _ como carcter dentro de una cadena, ste deber ir
precedido de un carcter de escape, que es la barra invertida o contrabarra.
Ejemplo: Queremos ver el Nombre de una serie de artculos que en la columna IVA contienen el
smbolo % al final.
SELECT Nombre FROM ARTICULOS WHERE IVA LIKE %\%;
Del carcter de escape se habl en el recurso: Reglas para escribir sentencias SQL de la
unidad anterior.
Ejercicio: BETWEEN, IN, LIKE
Realiza las siguientes consultas en SQL sobre la tabla empleados de la base de datos
bdempleados:

Seleccionar los nombres de los empleados cuya cuota de venta est comprendida entre
250000 y 300000, y cuyas ventas no estn comprendidas entre 50000 y 250000 ni entre
300000 y 500000 (usa BETWEEN siempre que sea posible).

15

UT_4 GBD
Seleccionar el nombre y las fechas de los contratos de los empleados cuyos contratos se

formalizasen entre 1989 y 2000, o bien su oficina sea la 21, la 13 o la 22. En el resultado
no aparecern los empleados cuyo jefe sea el de cdigo 108 (usa BETWEEN e IN).
Seleccionar el nombre y la edad de los empleados cuyo primer apellido no comience ni por G
ni por V (supn que todos los nombres propios son simples).
Seleccionar el nombre de los empleados cuyo ttulo no sea director de nada.

5.- Tratamiento de valores nulos.


Un dato es una unidad de informacin con sentido que se almacena en un campo. Dependiendo del
contenido de la informacin almacenada, los datos pertenecen a diferentes tipos: cadenas de
caracteres, fechas, o nmeros, etc.
Un valor nulo es un valor que no es asignable a ningn tipo de datos y que significa que no se ha
definido ningn valor inicial para ese dato, es decir, que el valor de ese dato es desconocido.
Un cero o un espacio en blanco es un valor que se ha asignado a un campo, por tanto el campo
tiene un contenido: el cero o el espacio en blanco.
Se dice que el contenido de una columna para un registro determinado es NULL si est
completamente vaca, no se carg en su momento ningn valor.
Para comprobar si en una columna hay un valor nulo se utiliza la expresin:
NombreColumna IS NULL
Por el contrario, para comprobar si en una columna hay algn valor, se emplea la expresin:
NombreColumna IS NOT NULL
La siguiente consulta muestra la matrcula y la fecha de entrada de los vehculos que estn
actualmente en nuestro taller de reparaciones, es decir, para los que no se ha definido una fecha de
salida.
SELECT Matrcula, FechaEntrada FROM REPARACIONES WHERE FechaSalida IS NULL;
Debes conocer
Los operadores aritmticos devuelven un valor nulo cuando alguno de sus operandos es nulo.
Ejercicio: IS [NOT] NULL
Realiza las siguientes consultas sobre la base de datos bdempleados:

Seleccionar los nombres de los empleados que no tengan jefe o no pertenezcan a ninguna

oficina. Slo se visualizarn los nombres de empleados que no tengan asignada cuota de
venta.
Seleccionar el cdigo y el nombre de la provincia de todas las oficinas que no tengan ni
objetivo de ventas ni ventas, o bien que el objetivo de ventas o las ventas sean 0, o su
supervit mayor de 100000.

16

UT_4 GBD

6.- Funciones.
Las funciones se usan dentro de expresiones y actan sobre los valores de las columnas de las
tablas, con variables o con constantes. Se utilizan en clusulas SELECT, WHERE, ORDER BY, etc.
Las funciones pueden:

Modificar la informacin original de la tabla.


Indicar alguna informacin sobre el elemento al que se aplica.
Una funcin est caracterizada por un nombre y cero o ms argumentos encerrados entre
parntesis. En MySQL es importante que entre el nombre de la funcin y el parntesis no exista
ningn espacio en blanco.
En el siguiente ejemplo se muestra la ejecucin de la funcin MOD de MySQL, que devuelve el
resto de la divisin entera de dos valores. Esta funcin requiere dos argumentos que, en este caso,
son dos valores constantes.
mysql> SELECT MOD(29,9);
1 rows in set (0.00 sec)
+--------------+
| mod(29,9) |
+--------------+
|

+--------------+
De forma general, podemos clasificar las funciones en las siguientes categoras:
Funciones aritmticas:

Estas funciones trabajan con datos de tipo numrico.


Los datos de tipo numrico incluyen los dgitos del 0 al 9, el punto decimal, y el signo menos.
Los literales numricos no se encierran entre comillas.
Funciones de cadena de caracteres:

Estas funciones trabajan con datos de tipo carcter.


Este tipo de datos incluyen cualquier carcter alfanumrico: letras, nmeros y caracteres
especiales.

Se deben encerrar entre comillas simples.


Mediante estas funciones podremos calcular el nmero de caracteres de una cadena,
convertir una cadena a maysculas o a minsculas, aadir o eliminar caracteres a la
izquierda o a la derecha, etc.

Funciones de manejo de fechas y horas:

En MySQL existen numerosas funciones para trabajar con las fechas y las horas.
Por defecto, el formato de almacenamiento de las fechas es AAAA-MM-DD y de las horas

HH:MM:SS, pero existen muchas funciones que nos permiten descomponer la fecha y la
hora, obtener la fecha y hora actuales, etc.

Funciones de comparacin:

17

UT_4 GBD
Se trata de funciones que comparan los valores de cada una de las columnas en el interior de
una fila para obtener: el menor o el mayor valor de ellos, as como comprobar si el valor de una
columna es nulo.
Debes conocer
En el siguiente documento te presentamos un resumen de las funciones de cada tipo que se utilizan
con ms frecuencia en MyQL y algunos ejemplos de aplicacin:
Resumen de las funciones ms frecuentes en MySQL.(Anexo del tema)
Para saber ms
Como hemos dicho, existen muchas funciones que pueden aplicarse a las columnas de una tabla.
En algunas herramientas grficas se encuentran accesibles todas las funciones disponibles
agrupadas por categoras.
Para consultar la documentacin relativa a las funciones del manual de MySQL en espaol pincha
en el siguiente enlace:
Funciones internas para MySQL.: http://dev.mysql.com/doc/refman/5.6/en/functions.html
de la fecha, no el nombre del mes.
Ejercicio: Funciones de manejo de cadenas.
Crea una nueva base de datos llamada bdfunciones. A continuacin, realiza las operaciones de
abajo. Ejecuta las sentencias en el cliente de lnea de comandos o en cualquier cliente grfico de
MySQL. Puedes recurrir al manual de MySQL para buscar informacin sobre las funciones
necesarias para realizar el ejercicio.

Aade a la base de datos creada una nueva tabla, llamada funcionescadena, con 3 campos

de tipos VARCHAR(100) BINARY, VARCHAR(20) y entero, respectivamente. El primer


campo ser la clave principal.
Desde Navicat, inserta 5 registros en la tabla creada. Los datos insertados en los campos de
tipo VARCHAR sern frases compuestas por varias palabras. Al menos uno de los datos
del primer campo contendr la letra T, y otro la letra t.
Selecciona el cdigo ASCII de la ltima letra del primer campo de todos los registros.
Selecciona la concatenacin de las 3 ltimas letras del primer campo seguidas de la cadena
YYY y seguidas de las dos primeras letras del segundo campo.
Selecciona la secuencia de caracteres correspondiente a los cuatro primeros caracteres de la
cadena contenida en el primer campo, pero cambiando cada carcter por el siguiente en la
tabla de cdigos ASCII (ej: ABCD se cambiara a BCDE).
Selecciona todos los registros que contengan una T en el primer campo.
Selecciona todos los registros que contengan una t en el primer campo.
Selecciona todos los registros que no contengan una T en el segundo campo.
Selecciona todos los registros de la tabla ordenados por el cdigo ASCII del segundo carcter
del segundo campo.
Ejercicio: Funciones numricas.
Realiza las operaciones de abajo. Recuerda que puedes buscar en el manual de MySQL las
funciones predefinidas apropiadas para realizar las consultas.

Aade a la base de datos bdfunciones una nueva tabla llamada usofuncionesnumericas.

Esta nueva tabla estar compuesta por cuatro campos de tipo entero pequeo, entero
normal, real simple y real doble, respectivamente, siendo el primero la clave principal.
Utiliza Workbench para aadir cuatro registros a la tabla creada. Aade, al menos, tres dgitos
decimales a cada valor de los dos ltimos campos.
Visualiza el contenido completo de la tabla.
Selecciona el resultado de multiplicar el primer y el segundo campo de la tabla por el valor de
la constante (PI). Utiliza una funcin para hacer referencia al valor de esta constante.

18

UT_4 GBD
Visualiza la raz cuadrada de todos los valores contenidos en el cuarto campo, dividida por 4.
Visualiza el resultado de redondear con 2 decimales los valores de los dos ltimos campos.
Visualiza el resultado obtenido al elevar el valor el contenido del tercer campo al valor
contenido en el segundo campo.

Ejercicio: Funciones de manejo de fechas y horas.


Realiza las siguientes operaciones:

Aade a la base de datos bdfunciones una nueva tabla llamada usofuncionesfechahora.

Esta nueva tabla estar compuesta por cuatro campos de tipo entero pequeo
autonumrico, date, datetime y time, siendo el primero la clave principal.
Utiliza Workbench para aadir a la tabla tres registros. Algunas fechas estarn dentro de los
ltimos 30 das.
Selecciona el valor del primer campo de la tabla para todos aquellos registros que tengan en
el tercer campo una fecha que est dentro de los ltimos 30 das.
Selecciona todos los registros que tengan un valor de segundo impar en el tercer o en el
cuarto campo.
Selecciona los nombres del da y del mes de las fechas contenidas en el tercer campo, de
todos los registros que contengan en el segundo campo una fecha que pertenezca a la
primera mitad de cualquier ao o al mes de septiembre.

7.- Consultas multitabla.


Hasta ahora nos hemos dejado guiar por Alejandra para aprender a realizar consultas sencillas
que manejaban una sola tabla. Ha llegado el momento de realizar consultas ms complejas para
obtener datos de varias tablas. Est claro que en el diseo de Talleres Faber intervienen
mltiples tablas y que en el trabajo diario con la base de datos estas consultas van a ser
frecuentes. Tendremos que seguir los pasos de Alejandra para aprender a combinar las tablas y
hacer consultas que muestren los resultados buscados.
En las consultas realizadas hasta ahora slo hemos utilizado una tabla que se indicaba a la derecha
de la clusula FROM, pero hay veces que una consulta necesita columnas de varias tablas.
Cuando utilizamos varias tablas tenemos que tener en cuenta:

Se pueden unir tantas tablas como deseemos.


En la clusula SELECT se pueden citar columnas de todas las tablas.
Si hay columnas que tienen el mismo nombre en distintas tablas de la clusula FROM, se
deben especificar escribiendo el nombre de la tabla antes del nombre de la columna:
NombreTabla.NombreColumna

Si el nombre de una columna no coincide en dos tablas no es necesaria la notacin anterior,


pero es conveniente.

En la clusula WHERE es necesario especificar el criterio que se sigue para combinar las
tablas ya que, si no se especifica, el resultado ser el producto cartesiano, que combina
todas las filas de una tabla con cada una de las filas de la otra. El producto cartesiano no
suele ser un resultado relevante.

En el siguiente ejemplo se obtiene un listado con los nombres y apellidos de los clientes y las
matrculas de los coches que nos han trado a reparar al talle. Debe observarse que si no se
especifica la clusula WHERE, se obtiene el producto cartesiano de las tablas CLIENTES y
VEHICULOS.
SELECT Nombre, Apellidos, Matricula FROM CLIENTES, VEHICULOS
WHERE CLIENTES.CodCliente = VEHICULOS.CodCliente;

19

UT_4 GBD
Para consultar los datos personales de los empleados cuya categora sea "oficial", junto con las
horas trabajadas en cada intervencin, ejecutaramos la siguiente consulta:
SELECT DNI, Nombre, Apellidos, Horas FROM EMPLEADOS, Intervienen
WHERE EMPLEADOS.CodEmpleado = Intervienen.CodEmpleado AND Categoria LIKE Oficial%;
En este ejemplo se efecta el producto cartesiano de la tabla de empleados con ella misma. Debe
observarse que en este caso resulta obligatorio el uso de un alias de tabla. Obtendremos todas las
posibles combinaciones de empleados con empleados.
SELECT * FROM empleados, empleados AS emp

Reflexiona
Cuando realizamos consultas a varias tablas y no especificamos las columnas por las que se
relacionan, el resultado de la consulta es el producto cartesiano, tal y como hemos explicado.
Este resultado casi siempre ser un error. En muy pocos casos nos interesa mezclar filas de una
tabla con filas de otra, sin ningn criterio para establecer esa combinacin.
Ejemplo: si combinamos en una consulta CLIENTES con VEHICULOS sin hacer coincidir el
CodCliente en ambas tablas, obtendremos un listado que mezcla cada cliente con todos los
vehculos de la tabla. Desde un punto de vista lgico esta consulta no tendra ningn sentido.
Ejercicio: Consultas multitabla y producto cartesiano.
Realiza, sobre la base de datos bdempleados, las siguientes consultas:

Obtener todos los campos de todos los registros de las tablas productos y pedidos. Es decir,
el producto cartesiano de estas tablas.

Todos los campos y registros de las tablas empleados y oficinas. Observa la forma de
nombrar los campos en la tabla resultado.

Los campos nombre, edad, oficina y ttulo de la tabla empleados, y los campos oficina, ciudad

y region de la tabla oficinas. No se incluirn en el resultado tuplas cuyo campo ttulo sea
representante.
En este apartado efectuaremos el producto cartesiano de la tabla productos consigo misma.
Se incluirn todos los campos de la primera relacin, pero slo el identificador de
fabricante y la descripcin del producto de la segunda. No se incluirn en el resultado
tuplas en las que ambos identificadores de fabricante sean idnticos.
Obtn una relacin que contenga, para cada trabajador menor de 45 aos, su nombre, su
ttulo, su fecha de contrato y la oficina en la que trabaja, incluyendo la ciudad de la oficina
as como sus ventas.

8.- Consultas de resumen.


Como hemos mencionado anteriormente, SQL proporciona un conjunto de funciones que nos
permiten resumir datos de la base de datos. Estas funciones actan sobre un grupo de filas para
obtener un nico valor, como si fuese un total final.
Las funciones de grupos de valores ignoran los valores nulos a la hora de realizar los clculos.
Estas funciones se muestran en la siguiente tabla:
FUNCIONES DE
COLUMNA
COUNT(Expresin o
Columna)

Descripcin
Cuenta el nmero de valores no nulos de la columna que aparece como
argumento. Podemos utilizar la clusula DISTINCT para contar el nmero de

20

UT_4 GBD
valores diferentes que aparecen en la columna. Si escribimos * cuenta las filas
que tengan valor no nulo.
SUM(Expresin o
Columna)

Calcula la suma de los valores numricos indicados en el argumento.

MIN(Expresin o
Columna)

Obtiene el valor mnimo del argumento indicado.

MAX(Expresin o
Columna)

Obtiene el valor mximo del argumento indicado.

AVG(Expresin o
Columna)

Obtiene la media aritmtica del argumento indicado. No considera los valores


nulos.

El argumento de estas funciones suele ser un nombre de columna.


A continuacin se obtiene el nmero total de horas trabajadas por los empleados:
SELECT SUM(Horas) FROM Intervienen;
Reflexiona
Analiza las siguientes consultas:
SELECT COUNT(DISTINCT Marca) MARCAS FROM VEHICULOS;
SELECT DISTINCT COUNT(Marca) MARCAS FROM VEHICULOS;
De qu forma interviene la clusula DISTINCT en ambas?
En la primera consulta contamos en la tabla VEHICULOS cuantas marcas distintas aparecen. Si la
marca aparece repetida se cuenta una sola vez.
En la segunda consulta la clusula DISTINCT se aplica despus de contar. Eliminara las filas
duplicadas que devuelva la consulta. En este caso no tiene sentido porque la consulta devuelve
un nico valor, una sola fila, por tanto no es posible que haya duplicados.

Retroalimentacin:
En la primera consulta contamos en la tabla VEHICULOS cuantas marcas distintas aparecen. Si la
marca aparece repetida se cuenta una sola vez.
En la segunda consulta la clusula DISTINCT se aplica despus de contar. Eliminara las filas
duplicadas que devuelva la consulta. En este caso no tiene sentido porque la consulta devuelve
un nico valor, una sola fila, por tanto no es posible que haya duplicados.
Ejercicio resuelto
Realiza las siguientes consultas a las tablas de TalleresFaber:

Precio medio de los recambios.


Nmero de vehculos que nos visitaron en Enero.
Tiempo mximo que dura una reparacin.
1.
2.
3.

SELECT Avg(PrecioReferencia) AS Precio medio recambiosFROM RECAMBIOS;


SELECT count(DISTINCT Matricula) AS Nmero de vehculos FROM REPARACIONES
WHERE FechaEntrada BETWEEN 2011-01-01 AND 2011-01-31;
SELECT Max(HorasEmpleadas) AS Horas empleadas FROM REPARACIONES;

Solucin:

21

UT_4 GBD
1.
2.
3.

SELECT Avg(PrecioReferencia) AS Precio medio recambiosFROM RECAMBIOS;


SELECT count(DISTINCT Matricula) AS Nmero de vehculos FROM REPARACIONES
WHERE FechaEntrada BETWEEN 2011-01-01 AND 2011-01-31;
SELECT Max(HorasEmpleadas) AS Horas empleadas FROM REPARACIONES;

Ejercicio: Consultas de resumen y funciones de columna.


Ejecuta sentencias para llevar a cabo las siguientes consultas sobre la base de datos
bdempleados, usando las funciones de columna:

Se pretende calcular la media de las edades de los empleados mayores de 50 aos. Este
resultado aparecer con el ttulo Media de mayores.

Se pretende obtener la media de las diferencias entre ventas y cuotas. No se considerarn los

empleados que tengan un nulo en su campo cuota o en su campo ventas. Este resultado
aparecer con el ttulo Desviacin media.
Se pretende calcular la media de las diferencias de las ventas de cada empleado menos las
ventas de la oficina que tiene asignada. El ttulo de esta columna ser Aportacin media
empleados.
Queremos visualizar el nmero de tuplas obtenido al realizar el producto cartesiano de la
tabla pedidos y la tabla clientes. El ttulo de este resultado ser Cuenta cartesiano.
Queremos visualizar el nmero de valores no nulos contenidos en la columna oficinas.objetivo
de la relacin que se obtiene al realizar el producto cartesiano de la tabla empleados y la
tabla oficinas. El ttulo de este resultado ser Cuenta objetivo cartesiano.
Visualizar la mayor edad de entre los empleados contratados antes de 1988.
Visualizar la mayor edad de los empleados cuya oficina est en la zona este o en la ciudad de
A Corua.
Visualizar la fecha del ltimo pedido que se hizo de un producto fabricado por aci.
Visualizar la media de los importes asociados al producto bisagra.

9.- Consultas agrupadas.


Cuando hemos recorrido con Alejandra las clusulas de la sentencia SELECT, hemos visto que
podamos utilizar GROUP BY para agrupar filas y HAVING para establecer condiciones en las
filas agrupadas. Combinando estas clusulas con las funciones de columna del apartado anterior,
Alejandra piensa que podr encontrar soluciones a cuestiones que hasta ahora no poda
resolver y que pueden ser tiles.
Por ejemplo, saber cuntos vehculos de cada marca visitan el taller podra resultar interesante a la
hora de especializar a los mecnicos en determinados motores.
En el apartado anterior hemos usado funciones de columna para calcular totales, obteniendo un
nico dato resumen. Las consultas agrupadas nos permitirn realizar clculos de grupo sobre filas
que tienen un valor coincidente en una o varias columnas, y obtener subtotales.
La siguiente imagen muestra una consulta agrupada:

Si queremos saber, por ejemplo, cuntos coches de cada marca han visitado nuestro taller? Hasta
ahora lo que podamos hacer era mostrar las filas de la tabla automviles, ordenadas por marca y
contar visualmente cuntas filas haba por cada marca, de la siguiente forma:

22

UT_4 GBD
SELECT Marca FROM VEHICULOS ORDER BY Marca;
Y si la tabla tuviera miles de filas? No podramos hacerlo as. Es el momento de recurrir a la
clusula GROUP BY.
Seguidamente se obtiene un listado con dos columnas: la marca y el nmero de vehculos que
visitan nuestro taller. La consulta devolver una fila por cada marca distinta, con el nombre de la
marca y el nmero de vehculos de esa marca que nos han visitado. El listado estar ordenado por
marcas.
SELECT Marca, count(*) AS Nmero de vehculos FROM VEHICULOS GROUP BY Marca ORDER BY Marca;

Tanto GROUP BY como HAVING se usan en consultas agrupadas. La sintaxis de estas consultas
es la siguiente:
SELECT NombreColumna,, Funcin, FROM NombreTabla [WHERE Condiciones..]
GROUP BY NombreColumaDeGrupo [HAVING Condiciones] [ORDER BY Criterio]
Estas clusulas combinadas con funciones de resumen nos permiten:

Contar grupos de elementos.


Sumar totales sobre grupos de elementos.
Obtener la media, valores mximos, etc.
En la lista de seleccin de una consulta agrupada slo pueden aparecer:

o
o
o
o

valores constantes
funciones de columna
columnas de agrupacin (columnas que aparecen en la clusula GROUP BY)
cualquier expresin basada en las anteriores.

A continuacin podemos observar dos consultas agrupadas. La primera es vlida, ya que la lista de
seleccin contiene elementos vlidos. Sin embargo, la segunda columna no est permitida, ya que
el campo rep es una columna simple que no est encerrada en una funcin de columna, ni est en
la lista de columnas de agrupacin.
SELECT SUM(importe), rep*10 FROM pedidos GROUP BY rep*10
SELECT SUM(importe), rep FROM pedidos GROUP BY rep*10
Del mismo modo que para establecer condiciones de bsqueda para filas individuales se utiliza
WHERE, para establecer condiciones de bsqueda para grupos de filas se utiliza HAVING. La
clusula HAVING se emplea para evaluar condiciones sobre las filas que devuelve GROUP BY.
Ahora se escribe la consulta agrupada del apartado anterior, pero nicamente nos mostrar las
marcas para las que el nmero de vehculos que han visitado nuestro taller sea mayor de 5:
SELECT Marca, count(*) AS Numero de vehiculos FROM VEHICULOS GROUP BY Marca HAVING count(*)>2
ORDER BY Marca;
Seguidamente queremos obtener las oficinas con un promedio de ventas de sus empleados mayor
que 500000.
SELECT SUM(ventas), oficina FROM empleados GROUP BY oficina HAVING AVG(ventas) > 500000

En la condicin que aparece detrs de la clusula HAVING slo pueden aparecer :

o
o
o

valores constantes
funciones de columna
columnas de agrupacin (columnas que aparecen en la clusula GROUP BY)

23

UT_4 GBD
o

cualquier expresin basada en las anteriores.

Ejercicio resuelto
Obtener la media de horas empleadas en cada tipo de actuacin, mostrando nicamente
aqullas cuya media no sea inferior a una hora.
SELECT Descripcion, AVG(Horas) AS Horas por trmino medio
FROM ACTUACIONES, Realizan
WHERE ACTUACIONES.Referencia = Realizan.Referencia
GROUP BY ACTUACIONES.Referencia
HAVING AVG(Horas) >= 1;
Solution:
SELECT Descripcion, AVG(Horas) AS Horas por trmino medio
FROM ACTUACIONES, Realizan
WHERE ACTUACIONES.Referencia = Realizan.Referencia
GROUP BY ACTUACIONES.Referencia
HAVING AVG(Horas) >= 1;
Ejercicio: GROUP BY
Realiza las siguientes consultas sobre la base de datos bdempleados:

La edad media de los trabajadores que tienen el mismo cargo. Se incluir el cargo en la
salida.

La fecha del contrato ms antiguo de los empleados de cada oficina. Se incluir el nmero de
cada oficina.

De entre los empleados que tienen el mismo jefe se obtendr la cuota mxima. Se incluir el
cdigo del jefe.

El nmero de empleados que tiene a su cargo cada empleado que es jefe. Se incluir el
cdigo del jefe. Implementa otra versin que adems incluya el nombre del jefe.

Para cada regin, la cuota mxima de venta de uno de sus trabajadores.


Para cada grupo de empleados que tengan la misma cuota se calcular la fecha de contrato

ms antigua y ms moderna. El resultado debe incluir la cuota. No se tendrn en cuenta


para calcular el resultado a los empleados cuya edad sea menor de 35.
Para cada grupo de empleados que tienen el mismo jefe se obtendr la media de sus cuotas.
No se incluirn en dichas medias las cuotas de empleados que tengan como jefe a uno
cuya cuota sea menor de 300000. Se incluir en el resultado el cdigo del jefe.
El importe total de cada producto vendido a partir de 2010. Se incluir en la salida el cdigo
del producto.
El nmero de pedidos en los que se ha visto involucrado cada artculo. Slo se tendrn en
cuenta los artculos cuyo precio sea mayor que 200 y menor que 2000.
El importe medio que se ha vendido a cada cliente que tenga un lmite de crdito inferior a
50000. En la salida se incluir el cdigo del cliente.
El importe mximo que se ha vendido a cada cliente. Slo se tendrn en cuenta los clientes
que tengan asignado un representante mayor de 40 aos. En la salida se incluir el cdigo
del cliente.
Para cada producto, la mayor edad de los empleados que lo vendieron. Se incluir en el
resultado el cdigo del producto.
Para cada producto, el mayor objetivo de las oficinas de los empleados que lo vendieron. Se
incluir en el resultado el cdigo del producto.
Ejercicio: HAVING.
Realiza las siguientes consultas sobre la base de datos bdempleados:

La suma de las ventas de los empleados de cada oficina. Se incluir en el resultado el cdigo
de cada oficina. No se incluirn en el resultado las oficinas cuyas ventas totales sean
menores de 200000 ni los empleados cuya oficina sea la 13.
La suma de las unidades vendidas de productos de un determinado fabricante. No se tendrn
en cuenta los pedidos cuyo representante pertenezca a una oficina del oeste. No se

24

UT_4 GBD
incluirn en el resultado final aquellas filas cuya suma de unidades al cuadrado sea menor
de 1000.
El promedio del lmite de crdito para los clientes asignados a cada empleado. No se tendrn
en cuenta los clientes cuyo lmite de crdito sea inferior a 30000. No se quieren en la
salida los datos de los clientes cuyo promedio del lmite de crdito sea inferior que 50000.
El resultado aparecer ordenado por el promedio. Se incluir en el resultado el cdigo del
representante del cliente.

10.- Unin de consultas.


Esta operacin se realiza sobre dos tablas o consultas que tienen el mismo nmero de columnas, y
stas son del mismo tipo.
El resultado es una tabla con las filas de la primera tabla y las filas de la segunda.
La sintaxis para realizar una UNION es:
SELECT..FROM..WHERE..
FROM.WHERE.

UNION

[ALL

DISTINCT]

SELECT.

Si no se especifica ALL o DISTINCT por defecto se usa DISTINCT.


Las condiciones en las que se establece una consulta de unin son:

Las consultas unidas deben tener el mismo nmero de columnas


Las columnas tendrn como encabezado, el resultado de la consulta, el identificador de
columna de la tabla que est a la izquierda del operador UNION.

Se pueden establecer criterios o condiciones para la unin, no unir todas las columnas de las
tablas, ordenar el resultado, etc.

Si en las tablas unidas hay filas que contienen la misma informacin, slo aparece una fila en
el resultado de la consulta y no dos repetidas. (UNION DISTINCT)

Se puede hacer que las filas repetidas aparezcan en el resultado de la consulta usando
UNION ALL.

Sobre el resultado final no se pueden aplicar otras clusulas como GROUP BY, nicamente
puede contener ORDER BY al final de la sentencia SELECT.

Ejercicio resuelto
Supongamos que tenemos dos tablas de FACTURAS: Una denominada FACTURAS_2013 con las
facturas emitidas ese ao y otra FACTURAS_2014 con las facturas emitidas en este ao.
Realizar una consulta de unin entre las facturas de ambas tablas correspondientes al mes de
enero.
SELECT * FROM FACTURAS_2013 WHERE FechaFactura BETWEEN 2013-01-01 AND 201301-31 UNION SELECT * FROM FACTURAS_2014 WHERE FechaFactura BETWEEN 2014-0101 AND 2014-01-31;
Solution:
SELECT * FROM FACTURAS_2013 WHERE FechaFactura BETWEEN 2013-01-01 AND 201301-31 UNION SELECT * FROM FACTURAS_2014 WHERE FechaFactura BETWEEN 2014-0101 AND 2014-01-31;
Ejercicio: UNION.
Se pretende seleccionar, de la base de datos bdempleados, mediante una nica consulta la
oficina, el nombre de los empleados, sus cuotas de venta y sus ventas, junto con la oficina, la
ciudad, el objetivo de ventas y las ventas de cada oficina. Slo se incluirn en el resultado a los
empleados cuyo contrato sea posterior a 1986. Por otra parte no se incluirn las oficinas de la zona
norte y centro. El resultado podr incluir tuplas repetidas. Los registros del resultado debern

25

UT_4 GBD
aparecer ordenados por el cdigo de la oficina y, si existiesen cdigos repetidos, stos se
ordenaran por el segundo campo (nombre o ciudad).

11.- Combinaciones internas.


Las combinaciones de tablas que hemos visto hasta ahora en consultas multitabla son
Composiciones o combinaciones internas. En estas se combina informacin procedente de dos o
ms tablas, formando filas relacionadas segn la condicin de bsqueda establecida con WHERE
que generalmente es la clave principal de una tabla y la clave ajena relacionada en la otra tabla.
Estas composiciones se denominan internas porque en el resultado no aparece ninguna fila
de una tabla que no tenga correspondencia con las filas de la tabla con la que se combina.
Las sintaxis de las combinaciones internas que vemos a continuacin son equivalentes:
SELECT FROM NombreTabla1 , NombreTabla2 WHERE condicin de relacin..
SELECT FROM NombreTabla1 INNER JOIN NombreTabla2 ON condicin de relacin..
Otras sintaxis de combinacin interna, igualmente equivalentes, son:
SELECT FROM NombreTabla1 JOIN NombreTabla2 ON condicin de relacin..
SELECT FROM NombreTabla1 JOIN NombreTabla2 WHERE condicin de relacin..
SELECT
.FROM
NombreTabla1
INNER
JOIN
NombreTabla2
USING(ColumnaRelacionada)..
En la salida de la siguiente consulta slo aparecen los datos de los clientes que tengan alguna
factura registrada. Los clientes que no tengan facturas no aparecen. Para los clientes con varias
facturas su nombre y apellidos se repite:
SELECT Nombre, Apellidos, IdFactura FROM CLIENTES INNER JOIN FACTURAS ON CLIENTES.CodCliente =
FACTURAS.CodCliente;

de otra forma:
SELECT Nombre, Apellidos, IdFactura FROM CLIENTES INNER JOIN FACTURAS USING(CodCliente);

A continuacin se combinan 3 tablas para obtener el importe total (suma de unidades*precio) de los
recambios sustituidos en cada reparacin:
SELECT REPARACIONES.IdReparacion, sum(Unidades * PrecioReferencia) AS 'Importe recambios' FROM
REPARACIONES INNER JOIN INCLUYEN ON REPARACIONES.IdReparacion=Incluyen.IdReparacion) INNER JOIN
RECAMBIOS ON Incluyen.IdRecambio=RECAMBIOS.IdRecambio GROUP BY IdReparacion;
Reflexiona
Compara las siguientes alternativas para definir combinaciones internas:
a.
b.

SELECT FROM NombreTabla1 INNER JOIN NombreTabla2 ON condicin de relacin..


SELECT .FROM NombreTabla1 INNER JOIN NombreTabla2
USING(ColumnaRelacionada)

Por qu podemos considerar que la sintaxis empleada en la opcin b es ms restrictiva que la de


la opcin a?

26

UT_4 GBD
Porque para relacionar las tablas con USING la columna por la cual se establece la combinacin
se tiene que llamar igual en ambas tablas, y para establecer una relacin las columnas deben
tener el mismo tipo de datos y tamao, pero pueden tener distinto nombre de columna.

Retroalimentacin:
Porque para relacionar las tablas con USING la columna por la cual se establece la combinacin
se tiene que llamar igual en ambas tablas, y para establecer una relacin las columnas deben
tener el mismo tipo de datos y tamao, pero pueden tener distinto nombre de columna.
Ejercicio: INNER JOIN
Realiza las siguientes consultas sobre la base de datos bdempleados, usando INNER JOIN:

Selecciona todos los campos de la tabla clientes junto a los datos de los pedidos que han
realizado.

Selecciona todos los campos de la tabla clientes junto a los datos de los pedidos que han

realizado, incluyndose nicamente la fecha de cada pedido y el importe total. Slo se


incluirn en el resultado a los clientes cuyo lmite de crdito sea mayor que 40000.
Seleccionar el nombre de cliente, su lmite de crdito, as como el nombre de su
representante y la regin a la que pertenece la oficina de ste.
Seleccionar el nombre de empleado (con el ttulo Nombre de empleado), la fecha de su
contrato, el cdigo de su oficina, el nombre de la provincia de la oficina, as como el
nombre del jefe del empleado (con el ttulo Nombre del jefe).
Seleccionar el nmero de cada pedido, su fecha y su importe, as como la ciudad en la que se
encuentra la oficina del representante que tiene asignado. No se incluirn en el resultado
los datos de pedidos cuyo importe sea inferior a 40000 o superior a 60000.

12.- Combinaciones externas.


Es una variedad de composicin de tablas que permite seleccionar algunas filas de una tabla
aunque stas no tengan correspondencia con las filas de la otra tabla con la que se combina.
Cuando no existe correspondencia en la segunda tabla se combina con NULL.
La combinacin externa puede expresarse de dos formas:

Combinacin externa a la izquierda: LEFT JOIN. Cada fila de la tabla colocada a la


izquierda que no se pueda combinar con ninguna fila de la segunda tabla, aade una fila al
resultado con los valores de las columnas de la primera tabla (izquierda) y NULL para
todas las columnas de la segunda que no han encontrado resultados coincidentes.

Combinacin externa a la derecha: RIGHT JOIN. Cada fila de la tabla colocada a la


derecha que no se pueda combinar con ninguna fila de la primera tabla, aade una fila al
resultado con los valores de las columnas de la segunda tabla (derecha) y NULL para
todas las columnas de la primera que no encuentren coincidencias.

La sintaxis equivalente en ambos casos para LEFT JOIN:


SELECT .FROM NombreTabla1 LEFT JOIN NombreTabla2 ON condicin de relacin..
SELECT .FROM NombreTabla1 LEFT JOIN NombreTabla2
USING(ColumnaRelacionada)
SELECT .FROM NombreTabla1 LEFT OUTER JOIN NombreTabla2 ON condicin de
relacin..
La sintaxis equivalente en ambos casos para RIGHT JOIN:

27

UT_4 GBD
SELECT .FROM NombreTabla1 RIGHT JOIN NombreTabla2 ON condicin de relacin..
SELECT .FROM NombreTabla1 RIGHT JOIN NombreTabla2
USING(ColumnaRelacionada)
SELECT .FROM NombreTabla1 RIGHT OUTER JOIN NombreTabla2 ON condicin de
relacin..
En la siguiente consulta, aunque tengamos algn cliente al que no le hayamos girado an ninguna
factura se mostrar su nombre y apellidos. En el IdFactura aparecer NULL:
SELECT Nombre, Apellidos, IdFactura FROM CLIENTES LEFT JOIN FACTURAS ON CLIENTES.CodCliente =
FACTURAS.CodCliente;

En este caso el resultado mostrara el nmero de las facturas aunque no existiera ningn cliente
relacionado.
En
las
columnas
nombre
y
apellidos
mostrara
NULL.
En realidad, este caso no podra darse puesto que hemos exigido en la definicin de la relacin que
no pueda haber ninguna factura que no est asociada a ningn cliente (Integridad referencial):
SELECT Nombre, Apellidos, IdFactura FROM CLIENTES RIGHT JOIN FACTURAS ON CLIENTES.CodCliente =
FACTURAS.CodCliente;
Ejercicio resuelto
Obtener un listado de los vehculos registrados en nuestra base de datos que no hayan
sufrido reparaciones.
SELECT VEHICULOS.Matricula, Marca, Modelo, Color, Avera
FROM VEHICULOS LEFT JOIN REPARACIONES
ON VEHICULOS.Matricula = REPARACIONES.Matricula
WHERE Avera IS NULL;
Solution:
SELECT VEHICULOS.Matricula, Marca, Modelo, Color, Avera
FROM VEHICULOS LEFT JOIN REPARACIONES
ON VEHICULOS.Matricula = REPARACIONES.Matricula
WHERE Avera IS NULL;
Ejercicio: LEFT JOIN/RIGHT JOIN
Realiza las siguientes combinaciones sobre la base de datos bdempleados, usando siempre el
operador de combinacin ms apropiado:

Se pretende obtener una relacin en la que aparezcan los datos de todas las oficinas junto a

los nombres y las edades de los directores de cada una de ellas (si una oficina no tiene
director entonces los datos de este aparecern en blanco).
Obtener una relacin que contenga por un lado los nombres y ttulos de los empleados, y
adems cdigos y la ciudad de las oficinas de los mismos. Aparecern los datos de todas
las oficinas, aunque estas no tengan empleados asignados.
Se pretende obtener una relacin en la que aparezcan los nombres de todos los empleados
que son jefe junto con los nombres de todos los empleados, aunque estos ltimos no
tengan jefe.

28

UT_4 GBD

13.- Subconsultas.
Siguiendo los pasos de Alejandra, parece que ya estamos listos para escribir cualquier tipo de
consulta en SQL que nos permita acceder a la informacin almacenada, pero no es as. En
muchas ocasiones para realizar una consulta necesitaremos los datos devueltos por otra consulta.
Investigaremos con Alejandra si este tipo de consultas, denominadas subconsultas, estn
recogidas en el SQL de nuestro SGBD MySQL, y cmo se utilizan.
Para entender la necesidad de realizar una subconsulta veremos un ejemplo: supongamos que
queremos obtener un listado con las actuaciones que se llevan a cabo en nuestro taller, cuyo
importe est por encima del importe medio.
Con lo que hemos visto hasta ahora necesitaramos hacer dos consultas:

Obtener el importe medio de las actuaciones.


Obtener un listado con la descripcin de las actuaciones cuyo importe sea mayor que el
importe medio.

En primer lugar haramos la primera consulta:


SELECT AVG(Importe) FROM ACTUACIONES;
Supongamos que el Importe medio obtenido sea 100. Ahora haramos la segunda consulta basada
en el resultado anterior:
SELECT Descripcion FROM ACTUACIONES WHERE Importe >100;

Las subconsultas permiten escribir estas dos consultas en una, escribiendo tras la clusula WHERE
otra sentencia SELECT. As el SELECT principal acta sobre las filas devueltas por el SELECT
anidado.
La sintaxis ser:
SELECT NombreColumna,. FROM NombreTabla, WHERE Expresin
OperadorRelacional (SELECT.)
En nuestro ejemplo sera:
SELECT Descripcion FROM ACTUACIONES WHERE Importe > <br />(SELECT avg(Importe) FROM
ACTUACIONES);
El tipo de dato de la expresin situada despus de WHERE debe coincidir con el tipo de dato
devuelto por la subconsulta.
Dentro de una consulta se pueden usar varias subconsultas enlazadas con el operador AND. Las
subconsultas se pueden usar dentro de otras sentencias como DELETE, INSERT, UPDATE o
CREATE.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando que
aparece encerrada entre parntesis, no puede contener la clusula ORDER BY, ni puede ser la
UNION de varias sentencias SELECT, adems tiene algunas restricciones en cuanto a nmero de
columnas segn el lugar donde aparece en la consulta principal. Estas restricciones las iremos
describiendo en cada caso.
Cuando se ejecuta una consulta que contiene una subconsulta, la subconsulta se ejecuta por cada
fila de la consulta principal.
Se aconseja no utilizar campos calculados en las subconsultas, ralentizan la consulta.

29

UT_4 GBD

Las consultas que utilizan subconsultas suelen ser ms fciles de interpretar por el usuario.
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de una
columna en la fila actual de la consulta principal, ese nombre de columna se denomina referencia
externa.
Una referencia externa es un nombre de columna que, estando en la subconsulta, no se refiere a
ninguna columna de las tablas designadas en la FROM de la subconsulta sino a una columna de las
tablas designadas en la FROM de la consulta principal. Como la subconsulta se ejecuta por cada
fila de la consulta principal, el valor de la referencia externa ir cambiando.
En la siguiente consulta se observa una subconsulta que contiene una referencia externa,
numemp, que es un campo de la tabla empleados, es decir, de la tabla origen de la consulta
principal.
SELECT numemp, nombre, (SELECT MIN(fechapedido) FROM pedidos WHERE rep= numemp) FROM
empleados;
Cuando se ejecuta la consulta anterior se coge el primer empleado y se calcula la subconsulta
sustituyendo numemp por el valor que tiene en el primer empleado, el 101; de este modo la
subconsulta obtiene la fecha ms antigua en los pedidos del representante 101. Seguidamente se
coge el segundo empleado y se calcula la subconsulta con numemp = 102 (numemp del segundo
empleado), y as sucesivamente hasta llegar al ltimo empleado. Al final obtenemos una lista con el
nmero, nombre y fecha del primer pedido de cada empleado. Si quitamos la clusula WHERE de
la subconsulta obtenemos la fecha del primer pedido de todos los pedidos no del empleado
correspondiente.
Las subconsultas pueden anidarse de forma que una subconsulta aparezca en la clusula WHERE,
por ejemplo, de otra subconsulta que a su vez forma parte de la consulta principal. En la prctica,
una consulta consume mucho ms tiempo y memoria cuando se incrementa el nmero de niveles
de anidamiento. La consulta resulta tambin ms difcil de leer, comprender y mantener cuando
contiene ms de uno o dos niveles de subconsultas.
En el siguiente ejemplo, por cada lnea de pedido, se calcula la subconsulta de clientes, y esto se
repite por cada empleado, en el caso de tener 10 filas de empleados y 200 filas de pedidos, la
subconsulta ms interna se ejecutara 2000 veces.
SELECT numemp, nombre FROM empleados WHERE numemp = (SELECT DISTINCT rep FROM pedidos WHERE
clie =
(SELECT numclie FROM clientes WHERE nombre = 'Julia Antequera'))
Cuando la subconsulta aparece en la lista de seleccin (vase ejemplo anterior) de la consulta
principal no puede devolver varias filas ni varias columnas, de lo contrario se genera error.
Muchos SQLs no permiten que una subconsulta aparezca en la lista de seleccin de la consulta
principal, pero eso no supone ningn problema, ya que normalmente se puede obtener lo mismo
utilizando como origen de datos las dos tablas. El resultado del ejemplo anterior se puede obtener
de la siguiente forma:
SELECT numemp, nombre, MIN(fechapedido) FROM empleados LEFT JOIN pedidos ON empleados.numemp =
pedidos.rep GROUP BY numemp, nombre

En la clusula FROM se puede encontrar una sentencia SELECT encerrada entre parntesis, pero
ms que subconsulta sera una consulta, ya que no se ejecuta para cada fila de la tabla origen sino
que se ejecuta una sola vez al principio, su resultado se combina con las filas de la otra tabla para
formar las filas origen de la SELECT primera y no admite referencias externas.
Se suelen utilizar subconsultas en las clusulas WHERE o HAVING cuando los datos que
queremos visualizar estn en una tabla pero para seleccionar las filas de esa tabla necesitamos
comprobar el valor de un dato que est en otra tabla. En este caso la subconsulta acta de

30

UT_4 GBD
operando dentro de la condicin.
En este ejemplo listamos el nmero y nombre de los empleados cuya fecha de contrato sea igual a
la primera fecha de todos los pedidos de la empresa.
SELECT numemp, nombre FROM empleados WHERE contrato = (SELECT MIN (fechapedido) FROM pedidos)
Reflexiona
En la prctica una consulta consume mucho ms tiempo y memoria cuando se incrementa el
nmero de niveles de anidamiento, adems resulta ms difcil de leer y de mantener cuando
contiene ms de dos niveles de anidamiento.
Ejercicio resuelto
Obtener los nombres de los empleados que no hayan intervenido en reparaciones desde
Enero.
SELECT Apellidos, Nombre FROM EMPLEADOS WHERE CodEmpleado NOT IN
(SELECT CodEmpleado FROM Intervienen, REPARACIONES WHERE
REPARACIONES.IdReparacion = Intervienen.IdReparacion AND FechaSalida>=2011-01-01);
Solution:
SELECT Apellidos, Nombre FROM EMPLEADOS WHERE CodEmpleado NOT IN
(SELECT CodEmpleado FROM Intervienen, REPARACIONES WHERE
REPARACIONES.IdReparacion = Intervienen.IdReparacion AND FechaSalida>=2011-01-01);
Ejercicio: Subconsultas en la lista de seleccin.
Utiliza subconsultas para obtener los siguientes resultados de la base de datos bdempleados:

Los cdigos y nombres de la ciudad de todas las oficinas junto a la cantidad mxima de
ventas de uno de sus trabajadores.

Los cdigos y nmeros de todos los pedidos cuyo importe sea mayor de 20000, junto con la
cuota del empleado que hizo el pedido.

Las descripciones de los productos junto al total de unidades vendidas y la media de los
importes vendidos del mismo.

Ejercicio: Subconsultas en las clusulas WHERE y HAVING.


Utiliza subconsultas para obtener los siguientes resultados de la base de datos bdempleados:

Las ciudades de las oficinas, los nombres de los empleados y sus fechas de contrato, de

todos los empleados cuyas ventas multiplicadas por dos sean mayores que la media de
ventas de todas las oficinas que tengan unas ventas mayores de 600000.
Los nombres de los empleados que sean representantes cuyas ventas supongan al menos el
15% del total de ventas de todas las oficinas de las regiones este y centro juntas.
Cada fabricante y la media del precio de sus productos, descartando los productos para los
que las existencias sean menores que 20. En el resultado no aparecern los datos de un
fabricante cuya media de precios de productos sea menor que la treintava parte de la
media de precios de los productos vendidos en 2010.
Los nombres de los clientes y de sus empleados asignados, para los que su lmite de crdito
sea mayor que la media de los importes de las tres primeras lneas de la tabla pedido. En
el resultado los registros aparecern ordenados por el nombre de los clientes.
La descripcin de todos los productos as como el mayor precio del producto asociado a dicha
descripcin. En el resultado final no aparecern las descripciones de los productos cuyo
mayor precio sea inferior al menor importe de todos los pedidos cuyo importe sea mayor de
100. El resultado final aparecer ordenado por las descripciones de los productos.

31

UT_4 GBD

13.1.- Tests de comparacin con subconsultas.


Existen cuatro tests de comprobacin de condiciones muy tiles cuando trabajamos con
subconsultas. Estos test son:
1.
2.
3.
4.

Test de comparacin con subconsulta.


Test de comparacin cuantificada.
Test de pertenencia a un conjunto.
Test de existencia.

1. Test de comparacin simple.


Se utiliza para comparar un valor de la fila que se est examinado con un nico valor producido por
la subconsulta. La subconsulta debe devolver una nica columna, si no se produce un error.
Si la subconsulta no produce ninguna fila o devuelve el valor nulo, el test devuelve el valor nulo; si la
subconsulta produce varias filas, SQL devuelve una condicin de error.
La sintaxis es la siguiente:

En el siguiente ejemplo se listan las oficinas cuyo objetivo sea superior a la suma de las ventas de
sus empleados. En este caso la subconsulta devuelve una nica columna y una nica fila (es un
consulta de resumen):
SELECT oficina, ciudad FROM oficinas WHERE objetivo > (SELECT SUM(ventas) FROM empleados WHERE
empleados.oficina = oficinas.oficina)

2. Test de comparacin cuantificada.


Compara el valor de la expresin con cada uno de los valores producidos por la subconsulta. La
subconsulta debe devolver una nica columna, si no se produce un error.
Tenemos el test ANY (algn, alguno en ingls) y el test ALL (todos en ingls).
La sintaxis es la siguiente:

Con el test ANY se evala la comparacin con cada valor devuelto por la subconsulta. Si
alguna de las comparaciones individuales produce el resultado verdadero, el test ANY
devuelve el resultado verdadero. Si la subconsulta no devuelve ningn valor, el test ANY

32

UT_4 GBD
devuelve falso. Si el test de comparacin es falso para todos los valores de la columna,
ANY devuelve falso. Si el test de comparacin no es verdadero para ningn valor de la
columna, y es nulo para al menos alguno de los valores, ANY devuelve nulo.
La siguiente subconsulta devuelve una nica columna con las sumas de las cuotas de los
empleados de cada oficina. Se listarn en el resultado las oficinas cuyo objetivo sea
superior a alguna de las sumas obtenidas.

SELECT oficina, ciudad FROM oficinas WHERE objetivo > ANY (SELECT SUM(cuota) <br />FROM empleados
GROUP BY oficina);

Con el test ALL se evala la comparacin con cada valor devuelto por la subconsulta. Si
todas las comparaciones individuales producen un resultado verdadero, el test devuelve
el valor verdadero. Si la subconsulta no devuelve ningn valor el test ALL devuelve el
valor verdadero. Si el test de comparacin es falso para algn valor de la columna, el
resultado es falso. Si el test de comparacin no es falso para ningn valor de la columna,
pero es nulo para alguno de esos valores, el test ALL devuelve valor nulo.
A continuacin se listan las oficinas cuyo objetivo sea superior a todas las sumas.
SELECT oficina, ciudad FROM oficinas WHERE objetivo > ALL (SELECT SUM(cuota) <br />FROM empleados
GROUP BY oficina);
Ejercicio: ANY y ALL.
Utiliza subconsultas para obtener los siguientes resultados de la base de datos bdempleados:

Los nombres y ttulos de los empleados para los que el 50% de su cuota sea mayor que las
ventas asociadas a alguna de las oficinas del centro o del oeste.

Los nombres de los empleados para los que el doble de sus ventas sea mayor que las ventas
asociadas a cada una de las oficinas del este.

Los nombres de los empleados para los que la diferencia entre sus cuotas y sus ventas sea

mayor que el 20% de los objetivos de cada una de las oficinas del este y mayor que el 10%
de las ventas de todas y cada una de las oficinas del oeste.
Los identificadores de los productos as como su descripcin, para todos aquellos productos
para los cuales la dcima parte de sus existencias sea mayor que la cantidad incluida en
todas y cada una de sus lneas de pedido (una a una, sin sumarlas). Analiza el resultado y
determina, manualmente, cuales son los que realmente cumplen la condicin que se
indica. Por qu se cuelan en el resultado tantos registros?
El cdigo de los pedidos y los nombres de los clientes que lo hicieron, para todos aquellos
pedidos cuyo representante tenga jefe o tenga una cuota mayor que 300000.
El nombre de los clientes y los nombres de sus representantes y sus edades, para todos los
clientes que tengan un lmite de crdito al menos 40 veces mayor que el importe de cada
una de las lneas de pedido que hizo.
El cdigo y ciudad de las oficinas, as como los nombres y edades de los jefes de los
directores de las mismas. En el resultado slo se incluirn los datos de las oficinas que
tienen un director cuyo jefe haya hecho algn pedido de los productos 2a44l o 41002 o
xk47.

3. Test de pertenencia a conjunto (IN/NOT IN).


Este test examina si el valor de la expresin es igual a uno de los valores incluidos en la lista de
valores producida por la subconsulta. La subconsulta debe generar una nica columna y las filas
que sean. Si la subconsulta no produce ninguna fila, el test da falso.
La siguiente subconsulta obtiene la lista de los nmeros de oficina del este, mientras que la consulta
principal obtiene los empleados cuyo nmero de oficina sea uno de los nmeros de oficina del este.
Por lo tanto se listan los empleados de las oficinas del este.

33

UT_4 GBD

SELECT numemp, nombre, oficina FROM empleado WHERE oficina IN (SELECT oficina FROM oficinas WHERE
region = 'este');

4. El test de existencia (EXISTS/NOT EXISTS).


El test EXISTS examina si la subconsulta produce alguna fila de resultados. Si la subconsulta
contiene filas, el test adopta el valor verdadero, si la subconsulta no contiene ninguna fila, el test
toma el valor falso, nunca puede tomar el valor nulo.
Con este test la subconsulta puede tener varias columnas, es irrelevante, ya que el test se fija no en
los valores devueltos sino en si hay o no filas en la tabla resultado de la subconsulta.
En la mayora de los casos, cuando se utiliza el test de existencia, habr que utilizar una referencia
externa. Si no se utiliza una referencia externa la subconsulta devuelta siempre ser la misma para
todas las filas de la consulta principal y en este caso se seleccionan todas las filas de la consulta
principal (si la subconsulta genera filas) o ninguna (si la subconsulta no devuelve ninguna fila).
A continuacin se obtiene el mismo resultado que el ejemplo del test IN. Observa que delante de
EXISTS no va ningn nombre de columna. En la subconsulta se pueden poner las columnas que
queramos en la lista de seleccin (hemos utilizado el *). Hemos aadido una condicin adicional al
WHERE, la de la referencia externa para que la oficina que se compare sea la oficina del empleado.
SELECT numemp, nombre, oficina FROM empleado WHERE EXISTS (SELECT * FROM oficinas WHERE region =
'este' AND empleados.oficina = oficinas.oficina)

Cuando se trabaja con tablas muy voluminosas el test EXISTS suele dar mejor rendimiento que el
test IN.

Ejercicio: IN/EXISTS
Utiliza subconsultas para obtener los siguientes resultados de la base de datos bdempleados:

Se piden los identificadores de los productos as como su descripcin, para todos aquellos

productos para los cuales la cuarta parte de sus existencias sean mayor que la cantidad
incluida en todas y cada una de sus lneas de pedido, pero saldrn los datos de aquellos
productos que tengan asociada al menos una lnea de pedidos.
La descripcin de los artculos y su cdigo, para los que se hayan hecho pedidos con un
importe mayor que 20000 y una cantidad mayor que 8 en una sola lnea de pedido.
Los cdigos y nmeros de pedido, as como el nombre del empleado que los hizo y la ciudad
de su oficina, para todas las lneas de pedido hechas sobre un producto cuyas existencias
sean mayores de 20.
Los nombres de los clientes y su lmite de crdito, para todos los clientes que tengan un
representante que pertenezca a una oficina que tenga objetivo y venta mayores que cero
(cuidado con los nulos).

34

Resumen de las funciones ms frecuentes en MySQL


Funciones aritmticas:
ABS (n)
MOD (m, n)
POWER (m, exponente)
ROUND (nmero [, m])
SQRT (n)
TRUNCATE (nmero, m)

Devuelve el valor absoluto de n. El valor absoluto es siempre un nmero positivo.


Devuelve el resto resultante de dividir m entre n.
Calcula la potencia de un nmero. Devuelve el valor de m elevado a un
exponente.
Devuelve el valor de numero redondeado a m decimales. Si se omite m,
devuelve nmero con 0 decimales y redondeado.
Devuelve la raz cuadrada de n. El valor de n no puede ser negativo.
Trunca los nmeros para que tengan un determinado nmero de dgitos de
precisin. Devuelve nmero truncado a m decimales. Si m es 0, devuelve
nmero con 0 decimales.

Funciones de cadenas de caracteres:


CONCAT (cad1, cad2)
LOWER (cad)
UPPER (cad)
LPAD (cad1, n, cad2)
RPAD (cad1, n, cad2)
LTRIM (cad)
RTRIM (cad)
SUBSTR (cad, m [,n])
REPLACE (cad,
cadena_bsqueda,
cadena_sustitucin)
LENGTH (cad)
INSTR (cad1, cad2)

Devuelve cad1 concatenada con cad2.


Devuelve cad convertida a minsculas.
Devuelve cad convertida a maysculas.
LPAD() aade caracteres a la izquierda de cad1 hasta que alcance la longitud n
cad2 es la cadena con la que re rellena por la izquierda (LPAD) o por la derecha
(RPAD)
cad1 puede ser una columna de una tabla o cualquier literal.
Suprime los blancos a la izquierda (LTRIM) o a la derecha (RTRIM) de una cadena.
Devuelve la subcadena de cad, desde la posicin indicada por m hasta tantos
caracteres como indique n. Si se omite n devuelve todos los caracteres a partir
de m.
Devuelve la cadena cad sustituyendo la cadena_bsqueda por la
cadena_sustitucin, todas las veces que aparezca.
Devuelve el nmero de caracteres de cad.
Devuelve la posicin de la primera ocurrencia de cad2 dentro de cad1.

Funciones de manejo de fechas y horas:


CURTIME()
CURRENT_TIME
CURRENT_TIME()
CURDATE()
CURRENT_DATE
CURRENT_DATE()
SYSDATE()
DAYNAME(fecha)
DAYOFMONTH(fecha)
MONTH(fecha)
MONTHNAME(fecha)
YEAR(fecha)
HOUR(hora)
MINUTE(hora)
SECOND(hora)
DATE_ADD(fecha, INTERVAL
expr intervalo)
TO_DAYS(fecha)

Devuelve la hora actual en formato HH:MM:SS

Devuelve la fecha actual en formato AAAA:MM:DD


Devuelve una cadena con la fecha y hora actual: AAAA:MM:DD HH:MM:SS
Devuelve el nombre del da de la semana.
Devuelve el nmero del da del mes.
Devuelve el nmero del mes de una fecha dada.
Devuelve el nombre del mes de la fecha dada.
Devuelve el ao de la fecha como un entero entre 1000 y 9999.
Devuelve la hora como un entero entre 0 y 59.
Devuelve los minutos como un entero entre 0 y 59.
Devuelve los segundos como un entero entre 0 y 59.
Devuelve el resultado de aadir o restar a una fecha el intervalo de tiempo
expresado como: n YEAR, n MONTH, n DAY, n HOUR, etc.
Devuelve el nmero de das transcurridos desde el ao 0.

Funciones de comparacin:
GREATEST(valor1, valor2, )
LEAST(valor1, valor2, )
IFNULL(expr1, expr2)

Obtiene el mayor valor de la lista.


Obtiene el menor valor de la lista.
Si expr1 no es NULL, la funcin devuelve expr1.
Si expr1 es NULL, la funcin devuelve expr2.

Ejemplos:
1) Obtener el valor de los recambios que tenemos en el taller sin decimales, de dos formas:
a) Truncando el resultado:
SELECT IdRecambio, Descripcion, TRUNCATE(Stock*PrecioReferencia),0) AS 'Valor almacen' FROM
RECAMBIOS;
b) Redondeando el resultado:
SELECT IdRecambio, Descripcion, ROUND((Stock*PrecioReferencia),0) AS 'Valor almacen' FROM RECAMBIOS;
Orservar el resultado, por ejemplo, para el IdRecambio= 'RV_222_666'.
2) Obtener el nombre completo de los empleados del taller, en maysculas.
SELECT UPPER(CONCAT(Nombre,' ', Apellidos)) FROM EMPLEADOS;
3) Extraer las letras de las matrculas de los vehculos.
SELECT SUBSTR(Matricula,5,4) AS 'Letras de las matrculas' FROM VEHICULOS;
4) Cuntos das han transcurrido desde que sali del taller el vehculo de matrcula 1515 DEF.
SELECT CURDATE()-FechaSalida AS 'Dias transcurridos' FROM REPARACIONES WHERE Matricula='1515 DEF';
5) A los 3 meses de retirar un coche llamamos al cliente para valorar su satisfaccin. Obtener un listado con las
matriculas y las fechas en que haremos la llamada transcurridos esos 3 meses.
SELECT Matricula, DATE_ADD(FechaSalida, INTERVAL 3 MONTH) FROM REPARACIONES;
6) Mostrar los telfonos de los clientes. En caso de que no tengan telfono mostrar sin telfono.
SELECT IFNULL(telefono, 'Sin telfono') FROM CLIENTES;
7) Mostrar la antigedad de los empleados en aos.
SELECT CONCAT(Nombre,' ', Apellidos) AS 'Nombre del empleado',
YEAR(CURDATE())-YEAR(FechaAlta)-(RIGHT(FechaAlta, 5) > RIGHT(CURDATE(), 5)) AS 'Aos de Antiguedad'
FROM EMPLEADOS;
8) Cuantos das, por trmino medio, est un coche en el taller. Mostrar nicamente 2 decimales?
SELECT ROUND(AVG(TO_DAYS(FechaSalida)-TO_DAYS(FechaEntrada)),2) AS 'Dias transcurridos'
FROM REPARACIONES;

También podría gustarte