Professional Documents
Culture Documents
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 aparezcan 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.
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
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
WHERE importe > 10000
UNION
SELECT numemp
FROM empleados
WHERE cuota < 10000
Esta es otra solucin, obtener por una parte los cdigos de los empleados con una
lnea de 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.
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
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
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
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.
Hemos supuesto que no pueden haber dos 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 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);
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 2
SELECT * INTO nuevaoficinas
FROM oficinas;
Ejercicio 3
SELECT * INTO nuevaproductos
FROM productos;
Ejercicio 4
SELECT * INTO nuevapedidos
FROM pedidos;
Ejercicio 5
UPDATE productos
SET precio = precio * 1.05 WHERE idfab = 'ACI';
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) ;
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.
Solucin 3
INSERT INTO oficinas
VALUES (30, 'Madrid', 'centro', null, 100000,0) ;
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);
Tambin se puede ver como las oficinas cuyo nmero no se encuentra entre las
oficinas asignados a los empleados.
Solucin 3
DELETE oficinas.*
FROM oficinas LEFT JOIN empleados
ON oficinas.oficina= empleados.oficina
WHERE empleados.numemp IS NULL ;
Otro planteamiento sera unir los empleados con 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;
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);
La solucin propuesta es una de la muchas posibles ya que cada uno puede elegir
el tipo de datos que prefiera siempre y cuando ese tipo permita introducir los
datos que tenemos en las tablas de ejemplo. Tambin la clusula NOT NULL se
puede poner en ms campos de los que tiene la solucin excepto en las columnas
que tengan filas sin valor en las tablas de ejemplo. Por ejemplo en oficina (el
empleado 110 no tiene oficina), en director (el empleado 106 no tiene director) y
en cuota (el empleado 110 no tiene cuota asignada. Pero las columnas edad,
titulo y ventas s las podemos definir con la restriccin NOT NULL. Para definir las
columnas cuota y ventas hemos elegido el tipo moneda (CURRENCY y MONEY son
sinnimos).
Ejercicio 2
CREATE TABLE oficinas (
oficina INT PRIMARY KEY,
ciudad TEXT(30),
region TEXT(20),
dir INT CONSTRAINT cf_dir REFERENCES empleados,
objetivo CURRENCY,
ventas CURRENCY );
Para definir la columna dir como clave fornea hemos elegido una restriccin1
(poner la definicin dentro de la definicin de la columna).
Ejercicio 3
En este caso la clave principal est formada por dos columnas idfab e idproducto
luego para definirla tenemos que utilizar necesariamente una restriccin2.
Ejercicio 4
CREATE TABLE clientes (
numclie INT ,
nombre TEXT(30) NOT NULL,
repclie INT CONSTRAINT cf_repclie REFERENCES empleados,
CONSTRAINT cp PRIMARY KEY (numclie) ) ;
Para exponer ms formas de definir una tabla aqu te hemos definido todas las
claves como restriccin2 la nica que es obligatoria en una restriccin2 es la
cf_prod ya que est compuesta por varias columnas.
Ejercicio 6
ALTER TABLE clientes
ADD COLUMN limitecredito MONEY;
Para aadir una nueva columna a una tabla que ya existe debemos emplear la
sentencia ALTER TABLE, y en nuestro caso la clusula ADD COLUMN (COLUMN es
opcional).
Ejercicio 7
ALTER TABLE empleados
ADD CONSTRAINT cf_oficina FOREIGN KEY (oficina) REFERENCES oficinas,
CONSTRAINT cf_director FOREIGN KEY (director) REFERENCES empleados;
Para aadir una definicin de clave fornea hay que aadir una restriccin2, se
pueden aadir varias restricciones en la misma sentencia ALTER TABLE.
Ejercicio 8
Solucin 1
ALTER TABLE empleados
ADD CONSTRAINT u_nombre UNIQUE (nombre);
Solucin 2
CREATE UNIQUE INDEX u_nombre ON empleados (nombre);
Para que no se puedan repetir los valores en la columna nombre hay que definir
un ndice nico, o bien definiendo una restriccin sobre la columna como te
indicamos en la solucin 1 o bien creando el ndice nico como te indicamos en la
solucin 2.
Ejercicio 9
Solucin 1
ALTER TABLE pedidos
ADD CONSTRAINT cp PRIMARY KEY (numpedido);
Para aadir una definicin de clave primaria hay que aadir una restriccin2.
Solucin 2
CREATE INDEX cp ON pedidos (numpedido) WITH PRIMARY ;
Ejercicio 11
DROP INDEX i_region ON oficinas ;
UNION
EJERCICIOS:
is not null
union
select cod_clie, nom_clie, 'cliente'
from clientes
where nro_tel is not null and
is not null
order by 3,2
union
select cod_clie, nom_clie, 'Cliente'
from clientes
union
select cod_vend, nom_vend, 'Vendedor'
from vendedores
order by 3
-------------------------------------------------------------------------------------
INNER JOIN
EJERCICIOS:
Liste factura, fecha, vendedor y cliente para las ventas del ao 2006 y
2007.
on d.nro_factu=f.nro_factu
order by a.descripcion
from nombre de talba join otra table on igualamos campos para listar todas las
facturas, y los clientes a los que he facturado para casos en que las facturas no
tengan campo cliente, .
left join es una unin a la izquierda muerto todos los campos de la izquierda y
solo los coicidentes
con la derecha. Con el reight Muesta todos los campos de la derecha y solo los
coicidentes con la derecha Con el full join muestra todos los campos
Se quiere saber los artculos que compraron los clientes que empiezan
con p. Liste cliente, articulo, cantidad e importe. Ordene por cliente
----------------------------------------------------------------------------
SUB-CONSULTAS
Subconsultas: Es una consulta que aparece dentro de la clusula WHERE
HAVING de otra sentencia SQL.
Subconsultas en la clusula WHERE
EJERCICIOS:
Liste nmero de factura, fecha y cliente para los casos en que todas
las veces que vino a comprar haya sido en el mes de febrero. Ordene
por cliente y fecha.
select *
from vendedores v
where v.cod_vend not in (
select f.cod_vend
from facturas f
where cod_clie in (1,6) )
where 80 < (
select avg (pre_unit*cant)
from detalle d
where a.cod_arti = d.cod_arti)
select descripcion
from articulos a
where cod_arti not in (
select distinct d.cod_arti
from detalle d)
and a.descripcion like '[d-p]%'
order by descripcion
-------------------------------------------------
EJERCICIOS:
Se quiere saber el importe vendido por fecha para los casos en que
ese promedio vendido sea inferior al importe promedio global. Rotule
como FECHA, IMPORTE.
-------------------------------------------------------------
SUMARIAS
EJERCICIOS:
que van de la d a la l.
----------------------------------------------------
VISTAS
EJERCICIOS:
select *
from [Detalle_ventas_vendedor]
select *
from [subtotales_ventas_vendedor]
select *
from [subtotales_ventas_vendedor]
select *
from [Detalle_ventas_vendedor]
select *
from [subtotales_ventas_vendedor]
where nom_vend like 'Miranda%'
select *
from [subtotales_ventas_vendedor]
where PROMEDIO_VENDIDO > 40
----------------------------------------------------
PROCEDIMIENTOS
ALMACENADOS
EJERCICIOS:
execute UPD_Vendedor
12, 'Pedro Perez', 'Lavalleja 250', 4205889, null, '20/03/2001'