Sei sulla pagina 1di 33

[estas son las tablas que usamos]

UNION

UNION: (OTRO DIA M PONGO A COMPLETAR TODO)

EJERCICIOS:

Se quiere saber que vendedores y clientes hay en la empresa; para los casos en que su
teléfono y dirección de e-mail sean conocidos. Se deberá visualizar el código, nombre y
si se trata de un cliente o de un vendedor. Ordene por la tercer columna y la segunda.

select cod_vend, nom_vend, 'vend' Tipo


from vendedores
where nro_tel is not null and [e-mail] is not null
union
select cod_clie, nom_clie, 'cliente'
from clientes
where nro_tel is not null and [e-mail] is not null
order by 3,2

Se quiere saber que artículos, clientes y vendedores hay en la empresa. Determine los
campos a mostrar y su ordenamiento

select cod_arti 'Código', descripcion 'Nombre', 'Articulo'Tipo


from articulos
union
select cod_clie, nom_clie, 'Cliente'
from clientes
union
select cod_vend, nom_vend, 'Vendedor'
from vendedores
order by 3

Se quiere saber que artículos hay en la empresa y cuáles han sido vendidos. Determine
Ud. las columnas a mostrar.

select cod_arti Código, descripcion Articulo, 'En Stock' Tipo


from articulos
union
select D.cod_arti, A.descripcion, 'Vendido'
from detalle D, Articulos A
where D.cod_arti = A.cod_arti
order by 3

Se quiere saber las direcciones tanto de clientes como de vendedores. Para el caso de
los vendedores, códigos entre 3 y 12. En ambos casos la direcciones deberán ser
conocidas. Rotule como NOMBRE, DIRECCION, INTEGRANTE (en donde indicará si es
cliente o vendedor). Ordenado por la primera columna y la última.
select nom_clie Nombre, direccion Direccion, 'Cliente' Integrante
from clientes
where direccion is not null
union
select nom_vend, direccion, 'Vendedor'
from vendedores
where direccion is not null and cod_vend between 3 and 12
order by 1,3

Se quiere saber que clientes hay en la empresa y quienes han comprado entre el
11/12/2002 y el 27/02/2003. Muestre el código, sin duplicarlos.

select cod_clie Codigo


from clientes
union
select cod_clie
from facturas
where fecha between 2002-11-12 and 2003-27-02

Idem al ejercicio anterior, sólo que además del código, identifique de donde obtiene la
información.

select cod_clie Código, 'Clientes' Desde


from clientes
union all
select cod_clie, 'Facturas'
from facturas F
where fecha between '2002-11-12' and '2003-27-02'
Se quiere saber que clientes hay en la empresa y quiénes han comprado; para el primer
caso para nombres que empiecen con letras que van de la “c” a la “l” y para el segundo
para facturas que oscilen entre 10 y 23. Muestre el código (no elimine los que se
repiten).

select cod_clie Código, 'Pasivo' Tipo


from clientes
where nom_clie like '[c-l]%'
union all
select cod_clie, 'Activo'
from facturas F
where F.nro_factu between 10 and 23

-------------------------------------------------------------------------------------

INNER JOIN

El INNER JOIN: Es otro tipo de composición de tablas. En lugar de hacer el producto


cartesiano completo, para cada una de las tablas busca directamente en la otra tabla las filas
que cumplen la condición.
LEFT OUTER JOIN: Toma todos los registros de la tabla izquierda, aunque no tengan ningún
registro coincidente (clave), en la tabla de la derecha.
RIGHT OVER JOIN: Realiza la selección de todos los registros de la tabla de la derecha,
aunque NO tenga ningún registros de la tabla de izquierda.

EJERCICIOS:

Liste factura, fecha, vendedor y cliente para las ventas del año 2006 y 2007.
select f.nro_factu, f.fecha,v.nom_vend, c.nom_clie
from facturas f inner join vendedores v
on f.cod_vend=v.cod_vend
inner join clientes c
on f.cod_clie=c.cod_clie
where year (f.fecha) in (2006, 2007)

Liste código de vendedor, nombre, fecha y factura; para las ventas en lo que va del
año.

select v.cod_vend, v.nom_vend, f.fecha, f.nro_factu


from facturas f
inner join vendedores v
on f.cod_vend=v.cod_vend
where year(f.fecha)=2007

Liste código de vendedor, nombre, fecha y factura; para las ventas en lo que va del
año.

select v.nom_vend, v.cod_vend, f.fecha, f.nro_factu


from facturas f
right join vendedores v
on f.cod_vend=v.cod_vend
where year(f.fecha)=2007 or f.fecha is null or f.nro_factu is null

Liste descripción, cantidad e importe; aun para aquellos artículos que no registran
ventas.

select a.descripcion, d.cant, d.pre_unit, d.pre_unit*d.cant as 'total'


from detalle d
full join articulos a
on d.cod_arti=a.cod_arti
full join facturas f
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 unión 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

Liste factura, fecha, vendedor, cliente, articulo, cantidad e importe; para las ventas de
febrero y marzo de los años 2006 y 2007 y siempre que el articulo empiece con letras
que van de la “a” a la “m”. Ordene por fecha, cliente y articulo.

select f.nro_factu, f.fecha, v.nom_vend, c.nom_clie, a.descripcion,


d.cant, d.pre_unit, d.cant*d.pre_unit
from facturas f full join vendedores v
on f.cod_vend=v.cod_vend
inner join detalle d
on f.nro_factu=d.nro_factu
inner join articulos a
on a.cod_arti=d.cod_arti
inner join clientes c
on f.cod_clie=c.cod_clie
where month(f.fecha)in (2, 3)
and year(f.fecha) in (2006, 2007)

Liste código de cliente,nombre, fecha y factura para las ventas del año 2007. Muestre
los clientes hayan comprado o no en ese año.

select c.cod_clie,c.nom_clie, f.fecha, f.nro_factu


from facturas f full join clientes c
on f.cod_clie=c.cod_clie
where year (f.fecha)=2007

Se quiere saber los artículos que compro el cliente 7 en lo que va del año. Liste articulo,
observaciones e importe.
select a.descripcion, c.nom_clie
from facturas f inner join clientes c
on f.cod_clie=c.cod_clie
inner join detalle d
on f.nro_factu=f.nro_factu
inner join articulos a
on d.cod_arti=a.cod_arti
where c.cod_clie=7
and year(f.fecha)=2007

Se quiere saber los artículos que compraron los clientes que empiezan con “p”. Liste
cliente, articulo, cantidad e importe. Ordene por cliente y articulo, este en forma
descendente. Rotule como CLIENTE, ARTICULO, CANTIDAD, IMPORTE.

select c.nom_clie as 'cliente',


a.descripcion as 'articulo' ,
d.cant as 'cantidad',
d.pre_unit as 'precio',
d.cant*d.pre_unit as 'total'
from facturas f inner join detalle d
on f.nro_factu=d.nro_factu
inner join articulos a
on d.cod_arti=a.cod_arti
inner join clientes c
on f.cod_clie=c.cod_clie
where c.nom_clie like '[p]%'
order by c.nom_clie desc, a.descripcion desc

----------------------------------------------------------------------------

SUB-CONSULTAS
Subconsultas: Es una consulta que aparece dentro de la cláusula WHERE ó HAVING de otra
sentencia SQL.
Subconsultas en la cláusula WHERE

Test De Comparación: (= , < , > ) Compara el valor de una expresión con un único valor
producido por una subconsulta

Test de Pertenencia A Conjunto (IN): Compara un valor de datos con una columna de
valores producida por una subconsulta. NOT IN: esta expresión significa que no está incluida
en la lista de valores generada por la subconsulta.

Test de Existencia (EXISTS): Comprueba si una subconsulta produce alguna fila de


resultados. Este test sólo se utiliza en subconsultas. NOT EXISTS: esta expresión invierte la
lógica.

Test de Cuantificados: ANY y ALL: Ambos tests comparan un valor de datos con la columna
de valores producidos por una subconsulta.

EJERCICIOS:

Se quiere saber que artículos no fueron vendidos el año pasado y que el precio unitario
del artículo oscile entre 2 y 6. Muestre el nombre del artículo, observaciones y precio
unitario.

select cod_arti, descripcion, observaciones, pre_unit


from articulos
where pre_unit between 2 and 6 and cod_arti not in (select distinct cod_arti
from facturas f, detalle d
where d.nro_factu=f.nro_factu and year(fecha)=2008)
Se quiere saber que clientes vinieron más de 5 veces el año pasado. Muestre el nombre
del cliente, número de factura y fecha. Rotule como CLIENTE, FACTURA, FECHA
VENTA. Ordene por nombre de cliente y fecha

select c.cod_clie as COD_CLIENTe, c.nom_clie as CLIENTES ,f.nro_factu as FACTURAS,


f.fecha as FECHA
from clientes c, facturas f
where c.cod_clie=f.cod_clie and year (fecha)=2008 and
5<(select count (*) from facturas f1 where f1.cod_clie=c.cod_clie and
year (fecha)=2008 )
order by c.nom_clie, f.fecha asc

Se quiere saber que clientes vinieron entre el 12/12/2004 y el 13/7/2007. Muestre el


nombre del cliente y su dirección de mail. Ordene por nombre de cliente.

select c.cod_clie, c.nom_clie, [e-mail]


from clientes c
where cod_clie in (select cod_clie from facturas
where fecha between '12/12/2004' and '13/7/2007')

Liste número 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 distinct c.cod_clie, c.nom_clie, [e-mail]


from clientes c, facturas f
where c.cod_clie=f.cod_clie and fecha between '12/12/2004' and '13/7/2007'

Muestre el número de factura y la fecha de venta para los casos en que por año se
hayan hecho menos de 9 ventas. Rotule como FACTURA, FECHA VENTA.

select f.nro_factu as FACTURA , f.fecha as FECHA_VENTA


from facturas f
where 9 > (
select count(*)
from facturas f1
where year (f.fecha) = year (f1.fecha) )

Muestre el número de factura, la fecha de venta, el artículo y el importe para los casos
en que para esa factura su importe total sea superior o igual a 150.

select f.nro_factu , f.fecha , a.descripcion , d.pre_unit*d.cant


from facturas f , articulos a , detalle d
where a.cod_arti = d.cod_arti and f.nro_factu = d.nro_factu and 150 < = (
select sum (d1.pre_unit*d1.cant)
from detalle d1
where d1.nro_factu = d.nro_factu)

Se quiere saber que vendedores nunca atendieron a estos clientes:6, 1. Muestre


solamente el nombre del vendedor. Rotule como VENDEDOR.

select *
from vendedores v
where v.cod_vend not in (
select f.cod_vend
from facturas f
where cod_clie in (1,6) )

Se quiere saber de que artículos superó el promedio de ventas de 80. Muestre el


nombre del artículo y sus observaciones. Rotule como ARTICULO, OBSERVACIONES.

select descripcion as ARTICULOS , observaciones as OBSERVACIONES


from articulos a
where 80 < (
select avg (pre_unit*cant)
from detalle d
where a.cod_arti = d.cod_arti)

Que artículos nunca se vendieron?. Tenga además en cuenta que su nombre comience
con letras que van de la “d” a la “p”. Muestre solamente la descripción de artículo.

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´

-------------------------------------------------

SUB-CONSULTAS CON HAVING

EJERCICIOS:

Se quiere saber la fecha de la primer venta y el importe de ventas por vendedor, para
los casos en que su promedio de ventas sea superior al importe promedio global.
Rotule como VENDEDOR, TOTAL VENTAS.

select nom_vend, min(fecha), sum(pre_unit*cant), avg(pre_unit*cant)


from facturas f, detalle d, vendedores v
where f.nro_factu=d.nro_factu and v.cod_vend=f.cod_vend
group by nom_vend
having avg(pre_unit*cant) > (select avg(pre_unit*cant) from detalle)

Se quiere saber el importe promedio y el importe de ventas por fecha y cliente, para los
casos en que los números de factura que oscilen entre 20 y 35 y que ese importe de
ventas sea superior o igual al promedio global. Rotule como FECHA VENTA, CLIENTE,
IMPORTE, PROMEDIO.

SELECT fecha, nom_clie, sum(pre_unit*cant), avg(pre_unit*cant)


from facturas f, clientes c, detalle d
where f.nro_factu= d.nro_factu and c.cod_clie = f.cod_clie and f.nro_factu between 20 and 35
group by fecha, nom_clie, d.cod_arti
having sum(pre_unit*cant) > (select avg(pre_unit*cant) from detalle )

Se quiere saber el importe vendido, la cantidad vendida por artículo, para los casos en
que los números de factura no sean uno de los siguientes:2, 10, 7, 13, 22 y que ese
importe promedio sea inferior al importe promedio de ese artículo.

SELECT descripcion, sum(d.pre_unit*cant), avg(d.pre_unit*cant)


from articulos a, detalle d
where a.cod_arti = d.cod_arti and nro_factu not in (10,2,7,13,22)
group by descripcion, d.cod_arti
having avg(d.pre_unit*cant) < (select avg(d1.pre_unit*cant) from detalle d1 where d1.cod_arti=
d.cod_arti)

Se quiere saber la cantidad vendida, el importe vendido y el promedio vendido por


fecha, siempre que esa cantidad vendida sea superior al promedio de la cantidad global.
Rotule como FECHA VENTA, CANTIDAD, IMPORTE, PROMEDIO. Ordene por fecha en
forma descendente.

select fecha, sum(cant), sum(pre_unit*cant), avg(pre_unit*cant)


from facturas f, detalle d
where f.nro_factu =d.nro_factu
group by fecha
having sum(cant) > (select avg(cant) from detalle)

Se quiere saber el promedio vendido por fecha y artículo para los casos en que las
cantidades vendidas oscilen entre 5 y 20 y que ese importe sea superior al importe
promedio de ese artículo. Rotule como FECHA VENTA, ARTICULO, FEC PRIMER
VENTA, PROMEDIO.

select fecha, descripcion, avg(d.pre_unit*cant)


from facturas f, articulos a, detalle d
where f.nro_factu = d.nro_factu and a.cod_arti = d.cod_arti and cant between 5 and 20
group by fecha, descripcion, d.cod_arti
having sum(d.pre_unit*cant) > (select avg(d1.pre_unit*cant) from detalle d1 where d1.cod_arti
=d.cod_arti)

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.

SELECT fecha, sum(pre_unit*cant)


from detalle d,facturas f
where f.nro_factu = d.nro_factu
group by fecha
having avg(pre_unit*cant) < (select avg(pre_unit*cant) from detalle)

-------------------------------------------------------------

SUMARIAS

EJERCICIOS:
Se quiere saber la cantidad de clientes que hay en la empresa.

select count (cod_clie) as cantidad


From dbo.clientes

Se quiere saber la cantidad de artículos que hay en la empresa.

select count (cod_arti) as cantidad


from dbo.articulos

Se quiere saber que cantidad de vendedores hay en la empresa.

select count (cod_vend) as cantidad


from dbo.vendedores

Se quiere saber la cantidad de ventas que hizo el vendedor de código 3.

select count (nro_factu) as cantidad


from dbo.facturas
where cod_vend = 3

Se quiere saber la cantidad vendida, la cantidad de ventas y el importe para la factura


10.

select sum(cant) as 'Cantidad vendida',count (nro_factu) as 'Cantidad de


ventas',sum(pre_unit*cant) as Importe
from dbo.detalle
where nro_factu=10

Se quiere saber cual fue la fecha de la primera y última venta. Rotule como
PRIMERVENTA, ULTIMA VENTA.

select max (fecha) as 'ultima venta' , min (fecha) as 'primera venta'


from dbo.facturas

Se quiere saber cual fue la máxima y la mínima cantidad que se vendió para el artículo
10.

select max(cant) as 'Maxima venta', min (cant) as 'Minima venta'


from dbo.detalle
where cod_arti = 10

Se quiere saber la cantidad total vendida, el monto y el importe promedio total; para
vendedores cuyo nombres comienzan con letras que van de la “d” a la “l”.

select sum (d.cant) as 'Cantidad total vendida' , sum (d.pre_unit) as 'Monto', avg
(d.pre_unit*d.cant) as 'Importe promedio total'
from dbo.detalle d, dbo.vendedores v
where v.nom_vend like '[d-l]%'

Se quiere saber el promedio del importe vendido, el total del importe vendido, el
promedio de la cantidad vendida y el total de la cantidad vendida.

select avg(pre_unit*cant) as 'Promedio importe', sum(pre_unit*cant) as 'Importe total',


avg(cant) as 'Promedio cantidad vendida', sum(cant) as 'Total cantidad vendida'
from dbo.detalle

Se quiere saber el total vendido, el promedio vendido y la cantidad total vendida para el
cliente de código 3.

select sum(d.cant) as 'Total vendido', avg(d.cant) as 'Promedio vendido'


from dbo.detalle d, dbo.clientes c
where c.cod_clie = 3

Se quiere saber la fecha de la primera venta, la cantidad total vendida y el monto total
vendido para los artículos que empiecen con “c”.

select min(f.fecha) as 'Fecha primer venta', sum(d.cant) as 'Cant total vendida',


sum(d.pre_unit) as 'Monto total'
from dbo.facturas f, dbo.detalle d, dbo.articulos a
where a.descripcion like 'c%'
Se quiere saber la cantidad total vendida y el monto total vendido para el periodo del
15/06/2005 al 15/03/2007.

select sum(d.cant) as 'Cantidad total ', sum(d.pre_unit*d.cant) as 'Monto total'


from dbo.detalle d, dbo.facturas f
where f.fecha between '15/06/2005' and '15/03/2007'

Se quiere saber la cantidad de veces y la última vez que vino el cliente de apellido
Abarca.

select count(f.nro_factu) as 'Cantidad de veces' , max(f.fecha) as 'Ultima visita'


from dbo.facturas f , dbo.clientes c
where c.nom_clie like 'Abarca%'

Se quiere saber el importe total vendido y el importe promedio vendido para números
de factura que no sean los siguientes: 13, 5, 17, 33, 24.

select sum(d.cant*pre_unit)as 'Importe total' , avg(d.cant*d.pre_unit) 'Importe promedio'


from dbo.detalle d, dbo.facturas f
where d.nro_factu= f.nro_factu and f.nro_factu not in (13,5,17,33,29)

----------------------------------------------------

VISTAS
EJERCICIOS:

Cree las siguientes vistas:

Detalle_Ventas_Vendedor: Liste la fecha, la factura, el codigo y nombre del vendedor, el


articulo, la cantidad e importe, para lo que va del año. Rotule como FECHA,
NRO_FACTURA, CODIGO_VENDEDOR, OMBRE_VENDEDOR, ARTICULO, CANTIDAD,
IMPORTE.

create view [Detalle_ventas_vendedor]


as (
select f.fecha as FECHA, f.nro_factu as NRO_FACTURA, v.cod_vend as
CODIGO_VENDEDOR,
v.nom_vend as NOMBRE_VENDEDOR, a.descripcion as ARTICULO,
d.cant as CANTIDAD, (d.pre_unit*d.cant) as IMPORTE
from facturas f, vendedores v, articulos a, detalle d
where year (fecha) = 2009)

select *
from [Detalle_ventas_vendedor]

Subtotales_Ventas_Vendedor: Se quiere saber el importe vendido y la cantidad de


ventas por vendedor. Rotule como VENDEDOR, IMPORTE_VENDIDO,
CANTIDAD_VENDIDA.

create view [subtotales_ventas_vendedor]


as (
select count (v.cod_vend) as CANTIDAD_VENTAS, v.nom_vend , sum(d.pre_unit*d.cant) as
IMPORTE
from facturas f, detalle d, vendedores v
where f.cod_vend = v.cod_vend and f.nro_factu = d.nro_factu
group by v.nom_vend )
select *
from [subtotales_ventas_vendedor]

Modifique las vistas según el siguientes detalle:


La vista creada en el punto b, agréguele la condición de que solo tome lo del año en
curso y que también muestre el promedio vendido y el código del vendedor.

alter view [subtotales_ventas_vendedor]


as (
select count (v.cod_vend) as CANTIDAD_VENTAS, v.nom_vend ,
sum(d.pre_unit*d.cant) as IMPORTE,
avg(d.pre_unit*d.cant) as PROMEDIO_VENDIDO,
v.cod_vend
from facturas f, detalle d, vendedores v
where f.cod_vend = v.cod_vend and f.nro_factu = d.nro_factu and year (fecha) = 2009
group by v.nom_vend, v.cod_vend)

select *
from [subtotales_ventas_vendedor]

Consulta las vistas según el siguiente detalle:


Llame a la vista creada en el punto 1.a pero filtrando por importes inferiores a $20.

select *
from [Detalle_ventas_vendedor]
where IMPORTE <= 20

Llame a la vista creada en el punto 1.b filtrando para el vendedor Miranda.

select *
from [subtotales_ventas_vendedor]
where nom_vend like 'Miranda%'
Llama a la vista creada en el punto 1.b filtrando para promedios superiores a 100.

select *
from [subtotales_ventas_vendedor]
where PROMEDIO_VENDIDO > 40

Elimine las vistas creadas en el punto 1 (no se olvide de colocar el nombre como
corresponde)

drop view [Detalle_ventas_vendedor]


drop view [subtotales_ventas_vendedor]

----------------------------------------------------

PROCEDIMIENTOS ALMACENADOS

EJERCICIOS:

Cree los siguientes SP:

LEGAJO-Detalle_Ventas: liste la fecha, la factura, el vendedor, el cliente, el artículo,


cantidad e importe. Este SP recibirá como parámetros de E un rango de fechas.

create procedure detalle_venta


@fecha1 as smalldatetime,
@fecha2 as smalldatetime
as
select f.fecha, f.nro_factu, v.nom_vend, c.nom_clie, a.descripcion, d.cant, (d.cant*d.pre_unit)
from clientes c, facturas f, vendedores v, articulos a, detalle d
where f.nro_factu = d.nro_factu and c.cod_clie = f.cod_clie and
a.cod_arti = d.cod_arti and v.cod_vend = f.cod_vend and
fecha between @fecha1 and @fecha2
execute detalle_venta '20/03/2008','13/11/2009'

CantidadArt_Cli : este SP me debe devolver la cantidad de artículos o clientes (según se


pida) que existen en la empresa.

create procedure CantidadArt_Clie


@opcion1 int
as
begin
if (@opcion1 = 1)
select count (*) from Articulos as Articulos
else
select count (*) from Clientes as Clientes
end

execute CantidadArt_Clie '1'

INS_Vendedor: Cree un SP que le permita insertar registros en la tabla vendedores.

create procedure INS_Vendedores


@cod_vend as int output,
@nom_vend as nvarchar (50),
@dir as nvarchar (50),
@nro_tel as int,
@e_mail as nvarchar (50),
@fec_nac as smalldatetime
as
begin
insert into vendedores (nom_vend, direccion, nro_tel, fec_nac) values
(@nom_vend, @dir, @nro_tel, @fec_nac)
set @cod_vend = @@identity
end

declare @a as int
execute INS_Vendedores
@a output, 'Pedro Perez', 'Lavalleja 250', 4205889, null, '20/03/2001'

UPD_Vendedor: cree un SP que le permita modificar un vendedor cargado.

create procedure UPD_Vendedor


@cod_vend int,
@nom_vend nvarchar (50),
@dir nvarchar (50),
@nro_tel int,
@correo nvarchar (50),
@fec_nac smalldatetime
as
update vendedores
set nom_vend = @nom_vend,
direccion = @dir,
nro_tel = @nro_tel,
[e-mail]= @correo,
fec_nac = @fec_nac
where cod_vend = @cod_vend

execute UPD_Vendedor
12, 'Pedro Perez', 'Lavalleja 250', 4205889, null, '20/03/2001'

DEL_Vendedor: cree un SP que le permita eliminar un vendedor ingresado.

create procedure DEL_Vendedores


@cod_vend as int
as
delete from vendedores
where cod_vend = @cod_vend

exec DEL_Vendedores

te tema se proporcionan ejemplos del uso de la instrucción SELECT.

A.Usar SELECT para recuperar filas y columnas


En el siguiente ejemplo se muestran tres fragmentos de código. En el primer ejemplo de código, se
devuelven todas las filas (no se especifica la cláusula WHERE) y todas las columnas (con *) de la
tabla Product de la base de datos AdventureWorks2012 .
Transact-SQL
USE AdventureWorks2012;
GO
SELECT *
FROM Production.Product
ORDER BY Name ASC;
-- Alternate way.
USE AdventureWorks2012;
GO
SELECT p.*
FROM Production.Product AS p
ORDER BY Name ASC;
GO
En este ejemplo se devuelven todas las filas (no se ha especificado la cláusula WHERE) y solo un
subconjunto de las columnas (Name,ProductNumber, ListPrice) de la tabla Product de la
base de datos AdventureWorks2012 . Además, se agrega un encabezado de columna.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT Name, ProductNumber, ListPrice AS Price
FROM Production.Product
ORDER BY Name ASC;
GO

En este ejemplo solo se devuelven las filas de Product que tienen una línea de productos de R y
cuyo valor correspondiente a los días para fabricar es inferior a 4.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT Name, ProductNumber, ListPrice AS Price
FROM Production.Product
WHERE ProductLine = 'R'
AND DaysToManufacture < 4
ORDER BY Name ASC;
GO

B.Usar SELECT con encabezados de columna y cálculos


En los siguientes ejemplos se devuelven todas las filas de la tabla Product. En el primer ejemplo
se devuelven las ventas totales y los descuentos de cada producto. En el segundo ejemplo se
calculan los beneficios totales de cada producto.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT p.Name AS ProductName,
NonDiscountSales = (OrderQty * UnitPrice),
Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY ProductName DESC;
GO

Ésta es la consulta que calcula el beneficio de cada producto de cada pedido de venta.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 -
UnitPriceDiscount)), ' for ',
p.Name AS ProductName
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY ProductName ASC;
GO

C.Usar DISTINCT con SELECT


En el siguiente ejemplo se utiliza DISTINCT para evitar la recuperación de títulos duplicados.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT DISTINCT JobTitle
FROM HumanResources.Employee
ORDER BY JobTitle;
GO

D.Crear tablas con SELECT INTO


En el primer ejemplo se crea una tabla temporal denominada #Bicycles en tempdb.
Transact-SQL
USE tempdb;
GO
IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL
DROP TABLE #Bicycles;
GO
SELECT *
INTO #Bicycles
FROM AdventureWorks2012.Production.Product
WHERE ProductNumber LIKE 'BK%';
GO

En el segundo ejemplo se crea la tabla permanente NewProducts.


Transact-SQL
USE AdventureWorks2012;
GO
IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL
DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks2012 SET RECOVERY BULK_LOGGED;
GO

SELECT * INTO dbo.NewProducts


FROM Production.Product
WHERE ListPrice > $25
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2012 SET RECOVERY FULL;
GO

E.Usar subconsultas correlacionadas


En el siguiente ejemplo se muestran consultas que son semánticamente equivalentes y se
demuestra la diferencia entre la utilización de la palabra clave EXISTS y la palabra
clave IN. Ambos son ejemplos de subconsultas válidas que recuperan una instancia de cada
nombre de producto cuyo modelo es un jersey de manga larga con logotipo y cuyos números
de ProductModelID coinciden en las tablas Product y ProductModel.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT DISTINCT Name
FROM Production.Product AS p
WHERE EXISTS
(SELECT *
FROM Production.ProductModel AS pm
WHERE p.ProductModelID = pm.ProductModelID
AND pm.Name LIKE 'Long-Sleeve Logo Jersey%');
GO

-- OR

USE AdventureWorks2012;
GO
SELECT DISTINCT Name
FROM Production.Product
WHERE ProductModelID IN
(SELECT ProductModelID
FROM Production.ProductModel
WHERE Name LIKE 'Long-Sleeve Logo Jersey%');
GO

En el siguiente ejemplo se utiliza IN en una subconsulta correlativa o repetitiva. Se trata de una


consulta que depende de la consulta externa de sus valores. Se ejecuta varias veces, una vez por
cada fila que pueda seleccionar la consulta externa. Esta consulta recupera una instancia del nombre
y apellido de cada empleado cuya bonificación en la tabla SalesPerson sea de 5000.00 y
cuyos números de identificación coincidan en las tablas Employee y SalesPerson.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT DISTINCT p.LastName, p.FirstName
FROM Person.Person AS p
JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN
(SELECT Bonus
FROM Sales.SalesPerson AS sp
WHERE e.BusinessEntityID = sp.BusinessEntityID);
GO

La subconsulta anterior de esta instrucción no se puede evaluar independientemente de la consulta


externa. Necesita el valorEmployee.EmployeeID, aunque este valor cambia a medida que el
Motor de base de datos de SQL Server examina diferentes filas deEmployee.
Una subconsulta correlativa se puede usar también en la cláusula HAVING de una consulta
externa. En este ejemplo se buscan los modelos cuyo precio máximo es superior al doble de la
media del modelo.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT p1.ProductModelID
FROM Production.Product AS p1
GROUP BY p1.ProductModelID
HAVING MAX(p1.ListPrice) >= ALL
(SELECT AVG(p2.ListPrice)
FROM Production.Product AS p2
WHERE p1.ProductModelID = p2.ProductModelID);
GO

En este ejemplo se utilizan dos subconsultas correlativas para buscar los nombres de los empleados
que han vendido un producto específico.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT DISTINCT pp.LastName, pp.FirstName
FROM Person.Person pp JOIN HumanResources.Employee e
ON e.BusinessEntityID = pp.BusinessEntityID WHERE pp.BusinessEntityID IN
(SELECT SalesPersonID
FROM Sales.SalesOrderHeader
WHERE SalesOrderID IN
(SELECT SalesOrderID
FROM Sales.SalesOrderDetail
WHERE ProductID IN
(SELECT ProductID
FROM Production.Product p
WHERE ProductNumber = 'BK-M68B-42')));
GO

F.Usar GROUP BY
En este ejemplo se busca el total de cada pedido de venta de la base de datos.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT SalesOrderID, SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
ORDER BY SalesOrderID;
GO

Debido a la cláusula GROUP BY, solo se devuelve una fila que contiene la suma de todas las ventas
por cada pedido de venta.

G.Usar GROUP BY con varios grupos


En este ejemplo se busca el precio medio y la suma de las ventas anuales hasta la fecha, agrupados
por Id. de producto e Id. de oferta especial.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS [Average Price],
SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY ProductID, SpecialOfferID
ORDER BY ProductID;
GO

H.Usar GROUP BY y WHERE


En el siguiente ejemplo se colocan los resultados en grupos después de recuperar únicamente las
filas con precios superiores a $1000.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductModelID, AVG(ListPrice) AS [Average List Price]
FROM Production.Product
WHERE ListPrice > $1000
GROUP BY ProductModelID
ORDER BY ProductModelID;
GO

I.Usar GROUP BY con una expresión


En este ejemplo se agrupa por una expresión. Puede agrupar por una expresión si ésta no incluye
funciones de agregado.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT AVG(OrderQty) AS [Average Quantity],
NonDiscountSales = (OrderQty * UnitPrice)
FROM Sales.SalesOrderDetail
GROUP BY (OrderQty * UnitPrice)
ORDER BY (OrderQty * UnitPrice) DESC;
GO

J.Usar GROUP BY con ORDER BY


En este ejemplo se busca el precio medio de cada tipo de producto y se ordenan los resultados por
precio medio.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID, AVG(UnitPrice) AS [Average Price]
FROM Sales.SalesOrderDetail
WHERE OrderQty > 10
GROUP BY ProductID
ORDER BY AVG(UnitPrice);
GO

K.Usar la cláusula HAVING


En el primer ejemplo se muestra una cláusula HAVING con una función de agregado. Agrupa las
filas de la tabla SalesOrderDetail por Id. de producto y elimina aquellos productos cuyas
cantidades de pedido medias son cinco o menos. En el segundo ejemplo se muestra una
cláusula HAVING sin funciones de agregado.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

En esta consulta se utiliza la cláusula LIKE en la cláusula HAVING.


USE AdventureWorks2012 ;
GO
SELECT SalesOrderID, CarrierTrackingNumber
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID, CarrierTrackingNumber
HAVING CarrierTrackingNumber LIKE '4BD%'
ORDER BY SalesOrderID ;
GO

L.Usar HAVING y GROUP BY


En el siguiente ejemplo se muestra el uso de las cláusulas GROUP BY, HAVING, WHERE y ORDER
BY en una instrucción SELECT. Genera grupos y valores de resumen pero lo hace tras eliminar los
productos cuyos precios superan los 25 $ y cuyas cantidades de pedido medias son inferiores a
5. También organiza los resultados por ProductID.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
WHERE UnitPrice < 25.00
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

M.Usar HAVING con SUM y AVG


En el siguiente ejemplo se agrupa la tabla SalesOrderDetail por Id. de producto y solo se
incluyen aquellos grupos de productos cuyos pedidos suman más de $1000000.00 y cuyas
cantidades de pedido medias son inferiores a 3.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS
Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
AND AVG(OrderQty) < 3;
GO

Para ver los productos cuyas ventas totales son superiores a $2000000.00, utilice esta consulta:
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00;
GO

Si desea asegurarse de que hay al menos mil quinientos elementos para los cálculos de cada
producto, use HAVING COUNT(*) > 1500para eliminar los productos que devuelven totales
inferiores a 1500 elementos vendidos. La consulta sería la siguiente:
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500;
GO

N.Usar la sugerencia del optimizador INDEX


En el ejemplo siguiente se muestran dos formas de usar la sugerencia del optimizador INDEX. En el
primer ejemplo se muestra cómo obligar al optimizador a que use un índice no clúster para
recuperar filas de una tabla, mientras que en el segundo ejemplo se obliga a realizar un recorrido de
tabla mediante un índice igual a 0.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT pp.FirstName, pp.LastName, e.NationalIDNumber
FROM HumanResources.Employee AS e WITH
(INDEX(AK_Employee_NationalIDNumber))
JOIN Person.Person AS pp on e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO

-- Force a table scan by using INDEX = 0.


USE AdventureWorks2012;
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
FROM HumanResources.Employee AS e WITH (INDEX = 0) JOIN Person.Person AS
pp
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO

M.Usar OPTION y las sugerencias GROUP


En el ejemplo siguiente se muestra cómo se usa la cláusula OPTION (GROUP) con una
cláusula GROUP BY.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO

O.Usar la sugerencia de consulta UNION


En el ejemplo siguiente se usa la sugerencia de consulta MERGE UNION.
Transact-SQL
USE AdventureWorks2012;
GO
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours,
SickLeaveHours
FROM HumanResources.Employee AS e1
UNION
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours,
SickLeaveHours
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO

P.Usar una instrucción UNION simple


En el ejemplo siguiente, el conjunto de resultados incluye el contenido de las
columnas ProductModelID y Name de las tablasProductModel y Gloves.
Transact-SQL
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO

-- Here is the simple union.


USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO

Q.Usar SELECT INTO con UNION


En el ejemplo siguiente, la cláusula INTO de la segunda instrucción SELECT especifica que la tabla
denominada ProductResultscontiene el conjunto final de resultados de la unión de las
columnas designadas de las tablas ProductModel y Gloves. Tenga en cuenta que la
tabla Gloves se crea en la primera instrucción SELECT.
Transact-SQL
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.ProductResults', 'U') IS NOT NULL
DROP TABLE dbo.ProductResults;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO

USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
INTO dbo.ProductResults
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO

SELECT ProductModelID, Name


FROM dbo.ProductResults;

R.Usar UNION con dos instrucciones SELECT y ORDER


BY
El orden de algunos parámetros empleados con la cláusula UNION es importante. En el ejemplo
siguiente se muestra el uso correcto e incorrecto de UNION en dos instrucciones SELECT en las
que se va a cambiar el nombre de una columna en el resultado.
Transact-SQL
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO

/* INCORRECT */
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
ORDER BY Name
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO

/* CORRECT */
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO

S.Usar UNION de tres instrucciones SELECT para


mostrar los efectos de ALL y los paréntesis
En los siguientes ejemplos se utiliza UNION para combinar los resultados de tres tablas que tienen
las mismas 5 filas de datos. En el primer ejemplo se utiliza UNION ALL para mostrar los registros
duplicados y se devuelven las 15 filas. En el segundo ejemplo se utilizaUNION sin ALL para eliminar
las filas duplicadas de los resultados combinados de las tres instrucciones SELECT y se devuelven 5
filas.
En el tercer ejemplo se utiliza ALL con el primer UNION y los paréntesis incluyen al
segundo UNION que no utiliza ALL. El segundo UNIONse procesa en primer lugar porque se
encuentra entre paréntesis. Devuelve 5 filas porque no se utiliza la opción ALL y se quitan los
duplicados. Estas 5 filas se combinan con los resultados del primer SELECT mediante las palabras
clave UNION ALL. Esto no quita los duplicados entre los dos conjuntos de 5 filas. El resultado final
es de 10 filas.
Transact-SQL
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeOne;
GO
IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeTwo;
GO
IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeThree;
GO

SELECT pp.LastName, pp.FirstName, e.JobTitle


INTO dbo.EmployeeOne
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
INTO dbo.EmployeeTwo
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
INTO dbo.EmployeeThree
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
-- Union ALL
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeOne
UNION ALL
SELECT LastName, FirstName ,JobTitle
FROM dbo.EmployeeTwo
UNION ALL
SELECT LastName, FirstName,JobTitle
FROM dbo.EmployeeThree;
GO

SELECT LastName, FirstName,JobTitle


FROM dbo.EmployeeOne
UNION
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeThree;
GO

SELECT LastName, FirstName,JobTitle


FROM dbo.EmployeeOne
UNION ALL
(
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeThree
);
GO

Potrebbero piacerti anche