Sunteți pe pagina 1din 20

Ejercicios

Ejercicios Tema 2. Las consultas simples


La lista de seleccin
1 Obtener una lista de todos los productos indicando para cada uno su idfab, idproducto,
descripcin, precio y precio con I.V.A. incluido (es el precio anterior aumentado en un 16%).
2 De cada pedido queremos saber su nmero de pedido, fab, producto, cantidad, precio
unitario e importe.
3 Listar de cada empleado su nombre, n de das que lleva trabajando en la empresa y
su ao de nacimiento (suponiendo que este ao ya ha cumplido aos).

Ordenacin de filas.
4 Obtener la lista de los clientes agrupados por cdigo de representante asignado,
visualizar todas la columnas de la tabla.
5 Obtener las oficinas ordenadas por orden alfabtico de regin y dentro de cada regin
por ciudad, si hay ms de una oficina en la misma ciudad, aparecer primero la que tenga
el nmero de oficina mayor.
6 Obtener los pedidos ordenados por fecha de pedido.

Seleccin de filas.
7 Listar las cuatro lneas de pedido ms caras (las de mayor importe).
8 Obtener las mismas columnas que en el ejercicio 2 pero sacando unicamente las 5
lneas de pedido de menor precio unitario.
9 Listar toda la informacin de los pedidos de marzo.
10 Listar los nmeros de los empleados que tienen una oficina asignada.
11 Listar los nmeros de las oficinas que no tienen director.
12 Listar los datos de las oficinas de las regiones del norte y del este (tienen que
aparecer primero las del norte y despus las del este).
13 Listar los empleados de nombre Julia.
14 Listar los productos cuyo idproducto acabe en x.

Solucin ejercicios tema 2. Las consultas simples


Ejercicio 1
SELECT
idfab,idproducto,descripcion,precio,
(precio * 1.16) AS iva_incluido
FROM productos

Los parntesis son opcionales, tambin se


puede poner como frmula de clculo: precio +
precio * 16 /100.

Ejercicio 2
SELECT numpedido, fab, producto,
cant, importe / cant AS precio_unitario,
importe
FROM pedidos

Ejercicio 3

SELECT nombre, date() - contrato AS


dias_trabajados, year(date()) - edad
AS ao_nacimiento
FROM empleados

Aqu hemos utilizado la funcin date() que


devuelve el da actual y hemos utilizado la
diferencia de fechas para saber cuntos das
han transcurrido entre las dos fechas. Para
saber el ao de nacimiento restamos al ao
actual la edad del empleado. Para obtener el
ao actual aplicamos la funcin year() (que
devuelve el ao de una fecha) sobre la fecha
actual (date())

Ejercicio 4
SELECT * FROM clientes

ORDER BY repclie

Ejercicio 5
SELECT *
FROM oficinas
ORDER BY region, ciudad, oficina DESC

Ejercicio 6
SELECT *
FROM pedidos
ORDER BY fechapedido

Ejercicio 7
SELECT TOP 4 *
FROM pedidos
ORDER importe DESC

Para obtener las ms caras tenemos que


ordenar por importe y en orden descendente
para que aparezca las ms caras primero.
Adems como slo queremos las cuatro
primeras utilizamos la clusula TOP 4.

Ejercicio 8
SELECT TOP 5 numpedido, fab,
producto, cant, importe / cant AS
precio_unitario, importe
FROM pedidos
ORDER BY 5

Ordenamos los pedidos por precio unitario


utilizando el n de columna, el precio unitario es
la quinta columna dentro de la lista de seleccin.
En este caso la ordenacin debe ser
ascendente.

Ejercicio 9
SELECT *
FROM pedidos
WHERE MONTH(fechapedido) = 3

MONTH(fecha) devuelve el nmero de mes de


la fecha.

Ejercicio 10
SELECT numemp
FROM empleados
WHERE oficina IS NOT NULL

Los empleados que tienen asignada una oficina


son los que tienen un valor en el campo oficina.

Ejercicio 11
SELECT oficina
FROM oficinas
WHERE dir IS NULL

El campo dir es el que nos dice quien es el


director de la oficina.

Ejercicio 12
SELECT *
FROM oficinas
WHERE region IN ('norte','este')
ORDER BY region DESC

Los valores se ponen entre comillas simples o


dobles ya que son valores alfanumricos.
Tambin se puede poner WHERE region =
'norte' OR region = 'este'.
Ordenamos desc para que primero aparezcan
las del norte.

Ejercicio 13
SELECT *
FROM empleados
WHERE nombre LIKE 'Julia *'

Los empleados cuyo nombre empiece por Julia,


observar que antes del * hay un espacio en
blanco para forzar a que el siguiente carcter
despus de la a sea un blanco y no coja por
ejemplo Julian.

Ejercicio 14
SELECT *
FROM productos
WHERE idproducto LIKE '*x'

Ejercicios tema 3. Las consultas multitabla


1 Listar las oficinas del este indicando para cada una de ellas su nmero, ciudad,
nmeros y nombres de sus empleados. Hacer una versin en la que aparecen slo las que
tienen empleados, y hacer otra en las que aparezcan las oficinas del este que no tienen
empleados.
2 Listar los pedidos mostrando su nmero, importe, nombre del cliente, y el lmite de
crdito del cliente correspondiente (todos los pedidos tienen cliente y representante).
3 Listar los datos de cada uno de los empleados, la ciudad y regin en donde trabaja.
4 Listar las oficinas con objetivo superior a 600.000 pts indicando para cada una de ellas
el nombre de su director.
5 Listar los pedidos superiores a 25.000 pts, incluyendo el nombre del empleado que
tom el pedido y el nombre del cliente que lo solicit.
6 Hallar los empleados que realizaron su primer pedido el mismo da en que fueron
contratados.
7 Listar los empleados con una cuota superior a la de su jefe; para cada empleado sacar
sus datos y el nmero, nombre y cuota de su jefe.
8 Listar los cdigos de los empleados que tienen una lnea de pedido superior a 10.000
ptas o que tengan una cuota inferior a 10.000 pts.

Solucin ejercicios tema 3. Las consultas multitabla


Ejercicio 1

SELECT oficinas.oficina, ciudad,


numemp, nombre
FROM oficinas INNER JOIN
empleados ON oficinas.oficina =
empleados.oficina
WHERE region = 'este'

Como la columna de emparejamiento


oficinas.oficina es clave principal en la tabla
oficinas, es mejor utilizar el JOIN que un
producto cartesiano. Emparejamos las dos
tablas por el campo oficina. Las oficinas que no
tengan empleados no salen (es un INNER).
Como queremos slo las oficinas del este
aadimos la clusula WHERE con la condicion.
El valor este debe ir entre comillas (es un valor
alfanumrico).
Observar que en la lista de seleccin la columna
oficina est cualificada (su nombre est
precedido del nombre de la tabla), es necesario
cualificarla porque en las dos tablas existe una
columna llamada oficina y el sistema no sabra
cul de las dos escoger.

SELECT oficinas.oficina, ciudad, numemp,


nombre
FROM oficinas LEFT JOIN empleados ON
oficinas.oficina = empleados.oficina
WHERE region = 'este'

Si queremos que tambin aparezcan las oficinas


que no tienen empleados cambiamos INNER
por LEFT (queremos todas las oficinas y la tabla
oficinas est a la izquierda de la palabra JOIN).
Ojo, si en la lista de seleccin ponemos
empleados.oficina en vez de oficinas.oficina, en
las filas de oficinas que no tienen empleados el
nmero de oficina aparece nulo.

SELECT oficinas.oficina, ciudad, numemp,


nombre
FROM empleados RIGHT JOIN oficinas ON
oficinas.oficina = empleados.oficina
WHERE region = 'este'

Esta SELECT es equivalente a la anterior pero


hemos cambiado LEFT por RIGHT porque ahora
la tabla oficinas est a la derecha de la palabra
JOIN.

Ejercicio 2
SELECT numpedido, importe, clientes.nombre
AS cliente, limitecredito
FROM pedidos INNER JOIN clientes ON
pedidos.clie = clientes.numclie

En este ejercicio no pueden haber pedidos sin


cliente, y lo que nos interesa son los pedidos,
luego tampoco tienen que aparecer los clientes
que no tienen pedidos, por lo tanto utilizamos un
INNER JOIN.

Ejercicio 3
SELECT empleados.*, ciudad, region
FROM empleados LEFT JOIN oficinas ON
empleados.oficina = oficinas.oficina

Aqu hemos utilizado LEFT JOIN para que


tambin salgan los empleados que no tienen
oficina asignada.
Como queremos todos los datos del empleado
utilizamos empleados.* para acortar.

Ejercicio 4
SELECT oficinas.*, nombre AS director
FROM empleados RIGHT JOIN oficinas ON
empleados.oficina = oficinas.oficina
WHERE objetivo > 600000

Nos interesan las oficinas con objetivo superior


a 600.000pts. luego nos tenemos que asegurar
que salgan todas incluso si no tienen director

asignado por eso utilizamos RIGHT JOIN.


En los valores numricos no utilizar el punto
para separar los miles (lo considerara coma
decimal y entendera 600 en vez de 600000).

Ejercicio 5
SELECT numpedido, importe,
empleados.nombre AS representante,
clientes.nombre AS cliente
FROM (pedidos INNER JOIN clientes ON
pedidos.clie = clientes.numclie) INNER JOIN
empleados ON pedidos.rep =
empleados.numemp
WHERE importe > 25000

En este ejercicio no pueden haber pedidos sin


representante ni cliente, y lo que nos interesa
son los pedidos, luego tampoco tienen que
aparecer los representantes que no tienen
pedidos ni los clientes que no tienen pedidos,
por lo tanto utilizamos un INNER JOIN.
Primero aadimos a cada lnea de pedido los
datos del cliente corespondiente (con el primer
INNER) y a cada fila resultante aadimos los
datos del representante correspondiente.
Nota: el representante que nos interesa es el
que ha realizado el pedido y ese dato lo
tenemos en el campo rep de pedidos por eso la
condicin de emparejamiento es pedidos.rep =
empleados.rep.
Si hubiesemos querido el nombre del
representante asignado al cliente, la condicin
hubiera sido clientes.repclie =
empleados.numemp.

Ejercicio 6
SELECT empleados.*
FROM empleados INNER JOIN pedidos ON
pedidos.rep = empleados.numemp
WHERE fechapedido = contrato

Los representantes que buscamos tienen un


pedido con la misma fecha que la de su
contrato, tenemos que aadir a los pedidos los
datos del representante correspondiente para
poder comparar los dos campos.

Ejercicio 7
SELECT empleados.*, jefes.numemp AS
num_jefe, jefes.nombre AS nombre_jefe,
jefes.cuota AS cuota_jefe
FROM empleados INNER JOIN empleados jefes
ON empleados.jefe = jefes.numemp
WHERE empleados.cuota > jefes.cuota

En una misma lnea necesito los datos del


empleado y los datos de su jefe, luego tengo
que combinar empleados con empleados. No
interesan los empleados que no tienen jefe
luego utilizo INNER. El alias de tabla es
obligatorio ya que combino empleados con la
misma.

Ejercicio 8
SELECT numemp
FROM empleados LEFT JOIN pedidos ON
pedidos.rep = empleados.numemp
WHERE importe > 10000 OR cuota < 10000

Una posible solucin es combinar pedidos con


empleados para poder seleccionar las lneas de
importe > 10000 o cuota < 10000. Hay que
utilizar LEFT para que puedan aparecer
empleados con cuota < 10000 que no tengan
pedidos.

SELECT rep
FROM pedidos

Esta es otra solucin, obtener por una parte los


cdigos de los empleados con una lnea de

WHERE importe > 10000


UNION
SELECT numemp
FROM empleados
WHERE cuota < 10000

pedido > 10000, por otra parte los cdigos de


los empleados con cuota < 10000 y finalmente
unir las dos listas con una UNION.

Ejercicios tema 4. Las consultas de resumen


1 Cul es la cuota media y las ventas medias de todos los empleados?
2 Hallar el importe medio de pedidos, el importe total de pedidos y el precio medio de
venta (el precio de venta es el precio unitario en cada pedido).
3 Hallar el precio medio de los productos del fabricante ACI.
4 Cul es el importe total de los pedidos realizados por el empleado Vicente Pantalla?
5 Hallar en qu fecha se realiz el primer pedido (suponiendo que en la tabla de
pedidos tenemos todos los pedidos realizados hasta la fecha).
6 Hallar cuntos pedidos hay de ms de 25000 ptas.
7 Listar cuntos empleados estn asignados a cada oficina, indicar el nmero de oficina
y cuntos hay asignados.
8 Para cada empleado, obtener su nmero, nombre, e importe vendido por ese
empleado a cada cliente indicando el nmero de cliente.
9 Para cada empleado cuyos pedidos suman ms de 30.000 ptas, hallar su importe
medio de pedidos. En el resultado indicar el nmero de empleado y su importe medio de
pedidos.
10 Listar de cada producto, su descripcin, precio y cantidad total pedida, incluyendo
slo los productos cuya cantidad total pedida sea superior al 75% del stock; y ordenado por
cantidad total pedida.
11 Saber cuntas oficinas tienen empleados con ventas superiores a su cuota, no
queremos saber cuales sino cuntas hay.

Solucin ejercicios tema 4. Las consultas de resumen


Ejercicio 1
SELECT AVG(cuota) AS cuota_media,
AVG(ventas) AS ventas_media
FROM empleados

Sale una nica fila con el resultado deseado.


Siempre que se utilicen expresiones o funciones
en la lista de seleccin, queda mejor utilizar un
alias de columna para que ese aparezca en el
encabezado del resultado.

Ejercicio 2
SELECT AVG(importe) AS importe_medio,
SUM(importe) AS importe_total,
AVG(importe/cant) AS precio_venta_medio
FROM pedidos

Ejercicio 3

El precio medio de venta es la media aritmtica


de los precios unitarios de cada pedido. El
precio unitario se calcula dividiendo el importe
del pedido por la cantidad del pedido:
importe/cant, por lo que ponemos
AVG(importe/cant).

SELECT AVG(precio) AS p_medio_ACI


FROM productos
WHERE idfab = 'ACI'

Ahora no nos interesan todos los productos sino


unicamente los del fabricante ACI, por lo que
aadimos la clusula WHERE para que antes
de calcular la media, elimine del origen de datos
los registros que no cumplan la condicin.

Ejercicio 4
SELECT SUM(importe) AS
total_pedidos_V_Pantalla
FROM empleados INNER JOIN pedidos ON
empleados.numemp = pedidos.rep
WHERE nombre = 'Vicente Pantalla'

El importe total lo tenemos que sacar de la tabla


de pedidos, y adems slo nos interesan los de
Vicente Pantalla. Como nos dan el nombre del
representante en vez de su nmero y en el
pedido slo tenemos el nmero de
representante tenemos que aadir a las lneas
de cada pedido, los datos del representante
correspondiente, por lo que el origen de datos
debe ser el que aparece en la FROM.

Ejercicio 5
SELECT MIN(fechapedido) AS primer_pedido
FROM pedidos

La fecha del primer pedido es la fecha ms


antigua de la tabla de pedidos.

Ejercicio 6
SELECT COUNT(*) AS
cuantos_pedidos_mayores
FROM pedidos
WHERE importe > 25000

Se poda haber utilizado tambin


COUNT(numpedido) o cualquier nombre de
columna que no pueda contener valores nulos,
pero COUNT(*) es mejor por ser ms rpido (la
diferencia se nota con tablas muy voluminosas).

Ejercicio 7
SELECT oficina, COUNT(*) AS
cuantos_empleados
FROM empleados
GROUP BY oficina

Con esta solucin obtenemos el listado pedido


pero no aparecen las oficinas que no tienen
empleados asignados ya que sacamos la
informacin de la tabla empleados y aparece
una fila con valor nulo en oficina que contiene el
nmero de empleados que no tienen oficina. Si
quisieramos listar incluso las que no tengan
empleados habra que recurrir a la solucin 2

Solucin 2
SELECT oficinas.oficina, COUNT(numemp) AS
cuantos_empleados
FROM empleados RIGHT JOIN oficinas ON
empleados.oficina = oficinas.oficina
GROUP BY oficinas.oficina

Utilizamos un RIGHT JOIN para que el origen de


datos incluya tambin una fila por cada oficina
que no tenga empleados.
En el GROUP BY y en la lista de seleccin hay
que indicar el campo oficina de la tabla oficinas,
si ponemos el de la tabla empleados, agrupar
todas las oficinas que no tienen empleados en
una fila (la columna empleados.oficina contiene
valor nulo para esas filas).
Aqu no podemos utilizar COUNT(*) por que las
oficinas sin empleados apareceran con 1 en la
columna cuantos_empleados ya que para esa
oficina hay una fila.

Ejercicio 8
SELECT numemp, nombre, clie AS cliente,
SUM(importe) AS total_vendido
FROM empleados INNER JOIN pedidos ON
pedidos.rep = empleados.numemp

Necesitamos la tabla de pedidos para el importe


vendido a qu cliente, necesitamos la tabla
empleados para el nombre del representante, la

GROUP BY numemp, nombre, clie

de clientes no la necesitamos ya que nos piden


el nmero de cliente y este est en pedidos.
La agrupacin bsica que debemos realizar es
por numemp y despus por clie, pero como
aparece el nombre del empleado en la lista de
seleccin, hay que incluirlo tambin en el
GROUP BY.
Despus de determinar la agrupacin bsica
que nos hace falta, siempre que se incluye una
columna adicional en el GROUP BY hay que
comprobar que esa nueva columna no cambia la
agrupacin bsica.
Por ejemplo no podramos aadir al GROUP BY
la columna fechapedido ya que se formaran
ms grupos.

Solucin 2
SELECT numemp, nombre, clie AS cliente,
SUM(importe) AS total_vendido
FROM empleados LEFT JOIN pedidos ON
pedidos.rep = empleados.numemp
GROUP BY numemp, nombre, clie

Si queremos que salgan todos los empleados


incluso los que no aparezcan en los pedidos
habra que sustituir el INNER por un LEFT.

Ejercicio 9
SELECT rep, AVG(importe) AS importe_medio
FROM pedidos
GROUP BY rep
HAVING SUM(importe) > 30000

No queremos todos los empleados, unicamente


los que tengan un importe total pedido superior
a 30.000, luego tenemos que poner la condicin
SUM(importe) > 30000. Como esta condicin
contiene una funcin de columna (SUM()) se
tiene que poner en la clusula HAVING ya que
selecciona filas de la tabla resultante no del
origen de datos.

Ejercicio 10
SELECT descripcion, precio, SUM(importe) AS
total_pedido
FROM productos INNER JOIN pedidos ON
pedidos.fab = productos.idfab AND
pedidos.producto = productos.idproducto
GROUP BY idfab, idproducto, descripcion,
precio, existencias
HAVING SUM(importe) > existencias * 0.75
ORDER BY 3

La agrupacin bsica es por idfab e idproducto


ya que son los dos campos que conjuntamente
identifican un producto.
Como descripcin y precio aparecen en la lista
de seleccin y no modifican la agrupacin
bsica los incluimos en el GROUP BY.
Como existencias aparece en el HAVING y no
modifica la agrupacin bsica lo incluimos
tambin el el GROUP BY.
Para calcular el 75% de las existencias
multiplicamos existencias por 0,75; observar que
en la sentencia SQL hay que utilizar el punto
para indicar los decimales.
Para indicar la columna de ordenacin no
podemos utilizar el alias campo, utilizamos el
nmero de orden de la columna dentro de la
lista de seleccin. En este caso la suma de
importes es la tercera columna.

Ejercicio 11

Consulta: distintas_oficinas
SELECT DISTINCT oficina
FROM empleados
WHERE ventas > cuota
Consulta: sumaria11
SELECT COUNT(*) AS cuantas_oficinas
FROM distintas_oficinas

Si contamos las oficinas directamente de la


tabla empleados nos salen 9 oficinas ya que la
funcin COUNT(nb columna) cuenta los valores
no nulos pero los valores repetidos los cuenta
tantas veces como se repiten, como tenemos
oficinas de se repiten en la columna oficina de
la tabla oficinas, esas oficinas son contadas
varias veces, hay que contar los valores
distintos.
En otros SQL la funcin COUNT puede llevar
delante del nombre de la columna la clusula
DISTINCT que indica que slo se tienen que
tener en cuenta valores distintos (no cuenta los
repetidos), por ejemplo COUNT(DISTINCT
oficina), es una opcin muy til que
desgraciadamente no incluye el SQL de
Microsoft JET. Para solucionar el problema se
resuelve con dos consultas, una con la cual nos
quedamos con los valores distintos (en la
solucin la consulta se llama distintas_oficinas),
y la otra que nos cuenta esos valores.

Ejercicios tema 5. Las subconsultas


Los ejercicios que te proponemos a continuacin se pueden resolver de varias maneras,
intenta resolverlos utilizando subconsultas ya que de eso trata el tema, adems un mismo
ejercicio lo puedes intentar resolver de diferentes maneras utilizandos distintos tipos de
condiciones, as un ejercicio se puede convertir en dos o tres ejercicios.
1 Listar los nombres de los clientes que tienen asignado el representante Alvaro Jaumes
(suponiendo que no pueden haber representantes con el mismo nombre).
2 Listar los vendedores (numemp, nombre, y n de oficina) que trabajan en oficinas
"buenas" (las que tienen ventas superiores a su objetivo).
3 Listar los vendedores que no trabajan en oficinas dirigidas por el empleado 108.
4 Listar los productos (idfab, idproducto y descripcin) para los cuales no se ha recibido
ningn pedido de 25000 o ms.
5 Listar los clientes asignados a Ana Bustamante que no han remitido un pedido
superior a 3000 pts.
6 Listar las oficinas en donde haya un vendedor cuyas ventas representen ms del 55%
del objetivo de su oficina.
7 Listar las oficinas en donde todos los vendedores tienen ventas que superan al 50%
del objetivo de la oficina.
8 Listar las oficinas que tengan un objetivo mayor que la suma de las cuotas de sus
vendedores.

Solucin ejercicios tema 5. Las subconsultas


Ejercicio 1
SELECT nombre
FROM clientes

Hemos supuesto que no pueden haber dos

WHERE repclie = (SELECT numemp FROM


empleados WHERE nombre = 'Alvaro Jaumes' );

empleados con el mismo nombre, de lo contrario


habra que aadir ANY antes de la subconsulta.

Ejercicio 2
Solucin 1
SELECT numemp, nombre, oficina
FROM empleados
WHERE oficina IN ( SELECT oficina FROM
oficinas WHERE ventas > objetivo );

Con esta solucin buscamos que la oficina del


empleado est en la lista de oficinas que tienen
ventas superiores a su objetivo.

Solucin 2
SELECT numemp, nombre, oficina
FROM empleados
WHERE EXISTS ( SELECT * FROM oficinas
WHERE empleados.oficina = oficinas.oficina
AND ventas > objetivo );

Con esta solucin buscamos que exista una


oficina igual al del empleado y que tenga ventas
superiores a su objetivo. El resultado ser el
mismo que con la solucin 1.

Solucin 3
SELECT numemp, nombre, oficina
FROM empleados
WHERE oficina = ANY ( SELECT oficina FROM
oficinas WHERE ventas > objetivo );

Con esta otra comparamos la oficina del


empleado con cada una de las oficinas que
tengan ventas superiores a su objetivo, si la
oficina del empleado es igual a alguna de esas
oficinas aparece el empleado en el resultado. El
resultado ser el mismo que con la solucin 1.

Ejercicio 3
Solucin 1
SELECT numemp, nombre, oficina
FROM empleados
WHERE NOT EXISTS ( SELECT * FROM oficinas
WHERE empleados.oficina = oficinas.oficina
AND dir = 108);

Obtenemos los empleados tales que no exista


una oficina igual a la suya que adems est
dirigida por el empleado 108, con esta solucin
s aparecen los empleados que no tienen
oficina.

SELECT numemp, nombre, oficina


FROM empleados
WHERE oficina NOT IN ( SELECT oficina FROM
oficinas WHERE dir = 108);

Con la subconsulta obtenemos la lista de las


oficinas dirigidas por el empleado 108. Al final se
obtienen los empleados cuya oficina no est en
esa lista. Pero no salen los empleados que no
tienen oficina asignada ya que su campo oficina
es nulo por lo que el resultado de la
comparacin es nulo, no es verdadero y no se
seleccionan. El problema se puede arreglar
indicando que tambin se tienen que
seleccionar los empleados con oficina nula:

Solucin 2
SELECT numemp, nombre, oficina
FROM empleados
WHERE ( oficina NOT IN ( SELECT oficina FROM
oficinas WHERE dir = 108) ) OR ( oficina IS
NULL);

Con la subconsulta obtenemos la lista de las


oficinas dirigidas por el empleado 108. Al final se
obtienen los empleados cuya oficina no est en
esa lista. Pero no salen los empleados que no
tienen oficina asignada ya que su campo oficina
es nulo por lo que el resultado de la
comparacin es nulo, no es verdadero y no se
seleccionan.

SELECT numemp, nombre, oficina


FROM empleados
WHERE oficina <> ALL ( SELECT oficina FROM
oficinas WHERE dir = 108);

Con esta solucin tenemos el mismo problema


que con NOT IN , cuando la oficina del
empleado es nula todos los resultados de las
comparaciones individuales son nulos por los
que el test ALL da nulo y no se seleccionan los

empleados con oficina nula.

Ejercicio 4
SELECT idfab, idproducto, descripcion
FROM productos
WHERE NOT EXISTS (SELECT * FROM pedidos
WHERE fab = idfab AND producto = idproducto
AND importe >= 25000);

En este caso es ms cmodo utilizar NOT


EXISTS ya que hay que preguntar por el idfab e
idproducto a la vez.

Ejercicio 5
SELECT numclie, nombre
FROM clientes
WHERE repclie IN ( SELECT numemp FROM
empleados WHERE nombre = 'Ana
Bustamante' )
AND numclie NOT IN ( SELECT clie FROM
pedidos WHERE importe > 3000);

Ejercicio 6
SELECT *
FROM oficinas
WHERE EXISTS ( SELECT * FROM empleados
WHERE ventas > objetivo * 0.55);

En una subconsulta todos los campos no


cualificados se presuponen de la tabla origen de
la subconsulta y slo si no existe ninguna
columna con ese nombre, la considera como
referencia externa, por eso no es necesario
cualificar ventas porque interpreta que es el
campo ventas de la tabla empleados.

Ejercicio 7
SELECT *
FROM oficinas
WHERE (objetivo * 0.5) <= ALL ( SELECT ventas
FROM empleados WHERE empleados.oficina =
oficinas.oficina );

Esta solucin no vale porque salen las oficinas


que no tienen empleados.
Hay que aadir una condicin para que se
consideren slo las oficinas con empleados
como muestra la solucin 1.

Solucin 1
SELECT *
FROM oficinas
WHERE ((objetivo * 0.5) <= ALL ( SELECT ventas
FROM empleados WHERE empleados.oficina =
oficinas.oficina ) )
AND ( EXISTS ( SELECT * FROM empleados
WHERE empleados.oficina = oficinas.oficina ) );

Solucin 2
SELECT *
FROM oficinas
WHERE (objetivo * .5) <= (SELECT MIN(ventas)
FROM empleados WHERE empleados.oficina =
oficinas.oficina);

Ejercicio 8
SELECT *
FROM oficinas
WHERE objetivo > ( SELECT SUM(cuota) FROM
empleados WHERE empleados.oficina =

Esta es otra posible solucin, calculamos la


menor venta de los empleados de la oficina y si
esta es mayor que el 50% del ojetivo de la
oficina quiere decir que todos los empleados de
esa oficina tienen ventas iguales o superiores.
Si la oficina no tiene empleados, la subconsulta
no devuelve ninguna fila y como estamos
utilizando una comparacin simple el resultado
es nulo, luego no salen las oficinas que no
tienen empleados.

oficinas.oficina);

Ejercicios tema 6. Actualizacin de datos


Como en estos ejercicios vamos a modificar los valores almacenados en la base de datos,
es conveniente guardar antes una copia de las tablas, en los cuatro primeros ejercicios
crearemos una copia de los datos almacenados para luego poder recuperar los valores
originales.
1 Crear una tabla (llamarla nuevaempleados) que contenga las filas de la tabla
empleados.
2 Crear una tabla (llamarla nuevaoficinas) que contenga las filas de la tabla oficinas.
3 Crear una tabla (llamarla nuevaproductos) que contenga las filas de la tabla
productos.
4 Crear una tabla (llamarla nuevapedidos) que contenga las filas de la tabla pedidos.
5 Subir un 5% el precio de todos los productos del fabricante ACI.
6 Aadir una nueva oficina para la ciudad de Madrid, con el nmero de oficina 30, con un
objetivo de 100000 y regin Centro.
7 Cambiar los empleados de la oficina 21 a la oficina 30.
8 Eliminar los pedidos del empleado 105.
9 Eliminar las oficinas que no tengan empleados.
10 Recuperar los precios originales de los productos a partir de la tabla
nuevosproductos.
11 Recuperar las oficinas borradas a partir de la tabla nuevaoficinas.
12 Recuperar los pedidos borrados en el ejercicio 8 a partir de la tabla nuevapedidos.
13 A los empleados de la oficina 30 asignarles la oficina 21.

Solucin ejercicios tema 6. Actualizacin


Ejercicio 1
SELECT * INTO nuevaempleados FROM empleados;
Ejercicio 2
SELECT * INTO nuevaoficinas FROM oficinas;
Ejercicio 3
SELECT * INTO nuevaproductos FROM productos;

Ejercicio 4
SELECT * INTO nuevapedidos FROM pedidos;
Ejercicio 5
UPDATE productos
precio =
SET precio = precio * 1.05 WHERE idfab = 'ACI';

Tambin se puede poner


precio + precio*0.05

Ejercicio 6
Solucin 1
INSERT INTO oficinas ( oficina, region, ciudad,
objetivo )
VALUES ( 30, 'centro','Madrid', 100000 );

Como no asignamos valor a todos los campos,


no hace falta poner todas las columnas en la
lista de columnas. Los campos dir y ventas se
rellenarn con el valor predeterminado.
Ojo! Si la tabla oficinas tiene definido en la
columna dir el valor predeterminado 0, al
intentar ejecutar la INSERT ocurrir un error
porque asigna 0 al campo dir , como dir es clave
ajena, antes de insertar comprueba que el valor
insertado en la clave ajena existe en la tabla
empleados, y el empleado 0 no existe por lo que
no puede insertar la oficina, el valor
predeterminado de dir debe ser nulo.

Solucin 2
INSERT INTO oficinas
(oficina,region,ciudad,dir,objetivo,ventas)
VALUES (30, 'centro', 'Madrid', null, 100000,0) ;
Solucin 3
INSERT INTO oficinas
VALUES (30, 'Madrid', 'centro', null, 100000,0) ;

Con esta solucin nos aseguramos que el valor


de dir sea nulo independientemente del valor
predeterminado y nos aseguramos que ventas
sea igual a cero.
En este caso como no especificamos una lista
de columnas tenemos que poner los valores en
el mismo orden que las columnas en vista
diseo de la tabla.

Ejercicio 7
UPDATE empleados SET oficina = 30 WHERE
oficina = 21;

Si ejecutamos esta sentencia antes de haber


creado la oficina 30, el sistema nos devuelve un
error.

Ejercicio 8
DELETE FROM pedidos WHERE rep = 105;

Ejercicio 9
Solucin 1
DELETE FROM oficinas WHERE NOT EXISTS
(SELECT *
FROM empleados WHERE empleados.oficina =
oficinas.oficina);

Si la oficina no tiene empleados asignados, no


existe ningn empleado con el nmero de esa
oficina.

Solucin 2
DELETE FROM oficinas WHERE oficina NOT IN
(SELECT oficina
FROM empleados) ;

Tambin se puede ver como las oficinas cuyo


nmero no se encuentra entre las oficinas
asignados a los empleados.

Solucin 3

Otro planteamiento sera unir los empleados con

DELETE oficinas.*
FROM oficinas LEFT JOIN empleados
ON oficinas.oficina= empleados.oficina
WHERE empleados.numemp IS NULL ;

sus oficinas y que tambin salgan las oficinas


que no tienen empleados (por eso LEFT en vez
de INNER) a partir de ah seleccionamos las
filas que no tienen valor en el campo numemp,
estas son las no tienen ningn empleado
relacionado. Como adems el origen est
basado en dos tablas es obligatorio poner
oficinas.* para indicar que se tienen que borrar
las filas de la tabla oficinas y no de empleados.

Ejercicio 10
UPDATE productos INNER JOIN
nuevaproductos
ON ( productos.idfab = nuevaproductos.idfab)
AND (productos.idproducto =
nuevaproductos.idproducto)
SET productos.precio = nuevaproductos.precio;

Unimos la tabla de productos con la tabla


nuevaproductos para tener en una misma fila el
precio que queremos cambiar y el precio antiguo
(el valor que queremos dejar).

Ejercicio 11
INSERT INTO oficinas
SELECT * FROM nuevaoficinas
WHERE oficina NOT IN (SELECT oficina FROM
oficinas);

En este caso insertamos en oficinas las oficinas


de nuevaoficinas cuyo nmero de oficina no
est en oficinas (es decir las que se han
borrado).

Ejercicio 12
INSERT INTO pedidos
SELECT * from nuevapedidos WHERE rep = 105;

Insertamos en pedidos los pedidos del


empleados 105 que se encuentran en la tabla
nuevapedidos.

Ejercicio 13
UPDATE empleados
SET oficina = 21 WHERE oficina = 30;

Si no hemos recuperado las oficinas borradas,


no permitir cambiar el campo oficina a 21 ya
que la oficina 21 es de las que se han borrado
en el ejercicio 9.

Ejercicios tema 7. Referencias cruzadas


1 Queremos saber de cada empleado sus ventas mensuales del ao 1990.
2 Modificar el ejercicio 1 para que junto al nmero de empleado tambin aparezca el
nombre del empleado.
3 Queremos saber las ventas mensuales de cada oficina distinguiendo meses de
distintos aos.
4 Se necesita una estadstica de cuntos empleados fueron contratados por ao en
cada oficina.
5 Queremos saber por ao las ventas realizadas en las distintas regiones.

Solucin ejercicios tema 7. Referencias cruzadas


Ejercicio 1

TRANSFORM SUM(importe)
SELECT rep AS empleado
FROM pedidos
WHERE year(fechapedido)=1990
GROUP BY rep
PIVOT MONTH(fechapedido);

Queremos calcular la suma de importes de los


pedidos realizados durante el ao 1990
agrupando por empleado y mes, queremos una
fila por empleado luego GROUP BY rep,
queremos que los meses aparezcan como
columnas dinmicas, luego PIVOT
MONTH(fechapedido), el calculo se hace en
base a los pedidos de 1990 luego el origen de la
FROM es pedidos con el WHERE para
seleccionar los pedidos de 1990, como columna
fija queremos el nmero de empleado luego la
lista de seleccin ser rep con un alias para que
el resultado salga ms aseado.

Ejercicio 2
TRANSFORM SUM(importe)
SELECT numemp AS empleado, nombre
FROM pedidos INNER JOIN empleados ON
pedidos.rep=empleados.numemp
WHERE year(fechapedido)=1990
GROUP BY numemp, nombre
PIVOT MONTH(fechapedido);

Ahora queremos que adems aparezca el


nombre del empleado, como no est en la tabla
pedidos sino en empleados, hay que aadir a
los pedidos los datos del empleado con el
INNER JOIN, ahora queremos dos columnas
fijas, la del nmero de empleado y su nombre
luego en la lista de seleccin aadimos nombre,
y como estamos en una sumaria nombre no
puede estar en la lista de seleccin si no est en
el GROUP BY luego lo aadimos a la clusula
GROUP BY.

Ejercicio 3
TRANSFORM SUM(importe)
SELECT oficina
FROM pedidos RIGHT JOIN empleados ON
pedidos.rep=empleados.numemp
GROUP BY oficina
PIVOT
year(fechapedido)&"/"&MONTH(fechapedido);

Ahora queremos agrupar por oficina, ao y mes,


el pivote sera ao y mes pero no se pueden
poner dos campos en la clusula PIVOT, lo que
hacemos es unir los dos campos en uno
mediantela concatenacin & adems para que
queden los valores ms claros los separamos
por una barra.

Ejercicio 4
TRANSFORM COUNT(numemp)
SELECT oficina
FROM empleados
GROUP BY oficina
PIVOT year(contrato);

En este caso elegimos como pivote el ao y


como encabezado de fila la oficina ya que
normalmente abrn ms oficinas que aos.

Ejercicio 5
TRANSFORM SUM(importe)
SELECT YEAR(fechapedido) AS anyo
FROM (pedidos INNER JOIN empleados ON
pedidos.rep=empleados.numemp) INNER JOIN
oficinas ON empleados.oficina=oficinas.oficina
GROUP BY YEAR(fechapedido)
PIVOT region;

En este ejercicios necesitamos los pedidos para


el importe vendido y la tabla oficinas para la
regin y para unirlas debemos utilizar la tabla
empleados para relacionar los pedidos con las
oficinas de los empleados que han realizado el
pedido.

Ejercicios tema 8. El DDL Lenguaje de Definicin de Datos Si tienes ya creadas


las tablas de los ejercicios del curso y no quieres perder los datos introducidos cmbiales el
nombre antes de empezar los ejercicios de esta unidad.

1 Crear la tabla empleados y definir su clave principal en la misma instruccin de


creacin.
2 Crear la tabla oficinas con su clave principal y su clave fornea ( la columna dir
contiene el cdigo de empleado del director de la oficina luego es un campo que hace
referencia a un empleado luego es clave fornea y hace referencia a la tabla empleados).
3 Crear la tabla productos con su clave principal.
4 Crear la tabla clientes tambin con todas sus claves y sin la columna limitecredito.
5 Crear la tabla pedidos sin clave principal, con la clave fornea que hace referencia a
los productos, la que hace referencia a clientes y la que indica el representante (empleado)
que ha realizado el pedido.
6 Aadir a la definicin de clientes la columna limitecredito.
7 Aadir a la tabla empleados las claves forneas que le faltan. (Si no tienes claro cuales
son te lo decimos ahora: la columna oficina indica la oficina donde trabaja el empleado y la
columna director indica quin dirige al empleado, su jefe inmediato).
8 Hacer que no puedan haber dos empleados con el mismo nombre.
9 Aadir a la tabla de pedidos la definicin de clave principal.
10 Definir un ndice sobre la columna region de la tabla de oficinas.
11 Eliminar el ndice creado.

Tablas de los ejemplos y ejercicios :


A lo largo de texto basaremos todos los ejemplos y ejercicios en las tablas que aparecen
a continuacin. Estas tablas estn orientadas a la didctica, no a un diseo ptimo.

Tabla empleados con los siguientes campos:


numemp: nmero del empleado
nombre : nombre y apellidos del empleado
edad : edad del empleado
oficina : nmero de la oficina donde trabaja el empleado, p.ej. Antonio Viguer trabaja en la
oficina 12 de Alicante
titulo : el cargo que desempea el empleado
contrato : fecha en que se contrat al empleado
jefe : nmero de su jefe inmediato, p.ej. El jefe de Antonio Viguer es Jos Gonzlez.
Observar que Luis Antonio no tiene jefe, es el director general.
cuota : cuota del empleado, sera el importe mnimo de ventas que debe alcanzar el
empleado en el ao
ventas : importe de ventas realizadas durante este ao

Tabla oficinas con los siguientes campos:


oficina: cdigo de la oficina
ciudad: ciudad donde est ubicada
region : regin a la que pertenece
dir : director de la oficina (su nmero de empleado) por ejemplo la oficina 12 tiene como
director el empleado104 Jos Gonzlez.
objetivo : objetivo de ventas que debe alcanzar la oficina
ventas: ventas de la oficina

Tabla clientes con los siguientes campos:


numclie: nmero de cliente
nombre : nombre y apellidos del cliente
repclie : n del representante asignado al
cliente.
Cada cliente tiene un representante asignado
(el que figura en repclie) que ser el que
generalmente le atienda.
limitecredito : lmite de crdito del cliente

Tabla productos con los


siguientes campos:
idfab: identificativo del fabricante
del producto
idproducto : cdigo que utiliza el
fabricante para codificar el
producto. Observar que aparecen
varias lneas con el mismo
idproducto (41003), por lo que la
clave principal de la tabla deber
ser idfab+idproducto
descripcion: nombre del
producto
precio: precio del producto
existencias: n de unidades del
producto que tenemos en
almacn.

Tabla pedidos:
codigo : n secuencial que sirve de clave principal
numpedido: n de pedido. Observar que un pedido puede tener varias lneas.
fechapedido : fecha del pedido
clie : cliente que efectua el pedido
rep : representante que tramita el pedido
fab: fabricante del producto que se pide
producto : idproducto del producto que se pide.
cant : cantidad que se pide del producto
importe : importe de la lnea de pedido

S-ar putea să vă placă și