Algunos Ejemplos SQL
Para terminar este repaso a las consultas simples practicarlas un poco, veamos
algunos ejemplos con la base de datos Northwind en SQL Server:
- Mostrar todos los datos de los Clientes de nuestra empresa:
SELECT * FROM Customers
- Mostrar apellido, ciudad y región (LastName, city, region) de los empleados de USA
(nótese el uso de AS para darle el nombre en español a los campos devueltos):
SELECT [Link] AS Apellido, City AS Ciudad, Region
FROM Employees AS E
WHERE Country = ‘USA’
- Mostrar los clientes que no sabemos a qué región pertenecen (o sea, que no tienen
asociada ninguna región) :
SELECT * FROM Customers WHERE Region IS NULL
- Mostrar las distintas regiones de las que tenemos algún cliente, accediendo sólo a
la tabla de clientes:
SELECT DISTINCT Region FROM Customers WHERE Region IS NOT NULL
- Mostrar los clientes que pertenecen a las regiones CA, MT o WA, ordenados por
región ascendentemente y por nombre descendentemente.
CODE SELECT * FROM Customers WHERE Region IN(‘CA’, ‘MT’, ‘WA’)
ORDER BY Region, CompanyName DESC
- Mostrar los clientes cuyo nombre empieza por la letra “W”:
SELECT * FROM Customers WHERE CompanyName LIKE ‘W%’
- Mostrar los empleados cuyo código está entre el 2 y el 9:
SELECT * FROM Employees WHERE EmployeeID BETWEEN 2 AND 9
- Mostrar los clientes cuya dirección contenga “ki”:
SELECT * FROM Customers WHERE Address LIKE ‘%ki%’
- Mostrar las Ventas del producto 65 con cantidades entre 5 y 10, o que no tengan
descuento:
SELECT * FROM [Order Details] WHERE (ProductID = 65 AND Quantity BETWEEN 5
AND 10) OR Discount = 0
Nota: En SQL Server, para utilizar nombres de objetos con caracteres especiales se
deben poner entre corchetes. Por ejemplo en la consulta anterior [Order Details] se
escribe entre corchetes porque lleva un espacio en blanco en su nombre. En otros
SGBDR se utilizan comillas dobles (Oracle, por ejemplo: “Order Details”) y en otros
se usan comillas simples (por ejemplo en MySQL).
P á g i n a 1 | 15
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT *
FROM [Link]
ORDER BY Name ASC;
-- Alternate way.
USE AdventureWorks2012;
GO
SELECT p.*
FROM [Link] 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 [Link]ás, se agrega
un encabezado de columna.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT Name, ProductNumber, ListPrice AS Price
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT Name, ProductNumber, ListPrice AS Price
FROM [Link]
WHERE ProductLine = 'R'
AND DaysToManufacture < 4
ORDER BY Name ASC;
GO
P á g i n a 2 | 15
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT [Link] AS ProductName,
NonDiscountSales = (OrderQty * UnitPrice),
Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM [Link] AS p
INNER JOIN [Link] AS sod
ON [Link] = [Link]
ORDER BY ProductName DESC;
GO
Ésta es la consulta que calcula el beneficio de cada producto de cada pedido de
venta.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 -
UnitPriceDiscount)), ' for ',
[Link] AS ProductName
FROM [Link] AS p
INNER JOIN [Link] AS sod
ON [Link] = [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT DISTINCT JobTitle
FROM [Link]
ORDER BY JobTitle;
GO
P á g i n a 3 | 15
D. Crear tablas con SELECT INTO
En el primer ejemplo se crea una tabla temporal denominada #Bicycles en tempdb.
SQLCopiar
USE tempdb;
GO
IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL
DROP TABLE #Bicycles;
GO
SELECT *
INTO #Bicycles
FROM [Link]
WHERE ProductNumber LIKE 'BK%';
GO
En el segundo ejemplo se crea la tabla permanente NewProducts.
SQLCopiar
USE AdventureWorks2012;
GO
IF OBJECT_ID('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
ALTER DATABASE AdventureWorks2012 SET RECOVERY BULK_LOGGED;
GO
SELECT * INTO [Link]
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
P á g i n a 4 | 15
SELECT DISTINCT Name
FROM [Link] AS p
WHERE EXISTS
(SELECT *
FROM [Link] AS pm
WHERE [Link] = [Link]
AND [Link] LIKE 'Long-Sleeve Logo Jersey%');
GO
-- OR
USE AdventureWorks2012;
GO
SELECT DISTINCT Name
FROM [Link]
WHERE ProductModelID IN
(SELECT ProductModelID
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT DISTINCT [Link], [Link]
FROM [Link] AS p
JOIN [Link] AS e
ON [Link] = [Link] WHERE 5000.00 IN
(SELECT Bonus
FROM [Link] AS sp
WHERE [Link] = [Link]);
GO
La subconsulta anterior de esta instrucción no se puede evaluar independientemente
de la consulta externa. Necesita el valor [Link], aunque este valor
cambia a medida que el Motor de base de datos de SQL Serverexamina diferentes
filas de Employee.
P á g i n a 5 | 15
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT [Link]
FROM [Link] AS p1
GROUP BY [Link]
HAVING MAX([Link]) >= ALL
(SELECT AVG([Link])
FROM [Link] AS p2
WHERE [Link] = [Link]);
GO
En este ejemplo se utilizan dos subconsultas correlativas para buscar los nombres de
los empleados que han vendido un producto específico.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT DISTINCT [Link], [Link]
FROM [Link] pp JOIN [Link] e
ON [Link] = [Link] WHERE [Link] IN
(SELECT SalesPersonID
FROM [Link]
WHERE SalesOrderID IN
(SELECT SalesOrderID
FROM [Link]
WHERE ProductID IN
(SELECT ProductID
FROM [Link] 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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT SalesOrderID, SUM(LineTotal) AS SubTotal
FROM [Link]
GROUP BY SalesOrderID
ORDER BY SalesOrderID;
GO
P á g i n a 6 | 15
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS [Average Price],
SUM(LineTotal) AS SubTotal
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductModelID, AVG(ListPrice) AS [Average List Price]
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT AVG(OrderQty) AS [Average Quantity],
NonDiscountSales = (OrderQty * UnitPrice)
FROM [Link]
GROUP BY (OrderQty * UnitPrice)
ORDER BY (OrderQty * UnitPrice) DESC;
GO
J. Usar GROUP BY con ORDER BY
P á g i n a 7 | 15
En este ejemplo se busca el precio medio de cada tipo de producto y se ordenan
los resultados por precio medio.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID, AVG(UnitPrice) AS [Average Price]
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012 ;
GO
SELECT SalesOrderID, CarrierTrackingNumber
FROM [Link]
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
P á g i n a 8 | 15
cuyas cantidades de pedido medias son inferiores a 5. También organiza los
resultados por ProductID.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS
Total
FROM [Link]
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:
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM [Link]
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(*) > 1500 para eliminar los productos que
devuelven totales inferiores a 1500 elementos vendidos. La consulta sería la
siguiente:
SQLCopiar
P á g i n a 9 | 15
USE AdventureWorks2012;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT [Link], [Link], [Link]
FROM [Link] AS e WITH
(INDEX(AK_Employee_NationalIDNumber))
JOIN [Link] AS pp on [Link] = [Link]
WHERE LastName = 'Johnson';
GO
-- Force a table scan by using INDEX = 0.
USE AdventureWorks2012;
GO
SELECT [Link], [Link], [Link]
FROM [Link] AS e WITH (INDEX = 0) JOIN [Link] AS
pp
ON [Link] = [Link]
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM [Link]
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
P á g i n a 10 | 15
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.
SQLCopiar
USE AdventureWorks2012;
GO
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours,
SickLeaveHours
FROM [Link] AS e1
UNION
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours,
SickLeaveHours
FROM [Link] 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 tablas ProductModel y Gloves.
SQLCopiar
USE AdventureWorks2012;
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO [Link]
FROM [Link]
WHERE ProductModelID IN (3, 4);
GO
-- Here is the simple union.
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM [Link]
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM [Link]
ORDER BY Name;
P á g i n a 11 | 15
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 ProductResults contiene 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.
SQLCopiar
USE AdventureWorks2012;
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO [Link]
FROM [Link]
WHERE ProductModelID IN (3, 4);
GO
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
INTO [Link]
FROM [Link]
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM [Link];
GO
SELECT ProductModelID, Name
FROM [Link];
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.
SQLCopiar
P á g i n a 12 | 15
USE AdventureWorks2012;
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO [Link]
FROM [Link]
WHERE ProductModelID IN (3, 4);
GO
/* INCORRECT */
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM [Link]
WHERE ProductModelID NOT IN (3, 4)
ORDER BY Name
UNION
SELECT ProductModelID, Name
FROM [Link];
GO
/* CORRECT */
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM [Link]
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM [Link]
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 utiliza UNION sin ALL para eliminar las filas duplicadas de los resultados
combinados de las tres instrucciones SELECT y se devuelven 5 filas.
P á g i n a 13 | 15
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 UNION se 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 SELECTmediante las palabras clave UNION ALL. Esto no quita los
duplicados entre los dos conjuntos de 5 filas. El resultado final es de 10 filas.
SQLCopiar
USE AdventureWorks2012;
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
IF OBJECT_ID ('[Link]', 'U') IS NOT NULL
DROP TABLE [Link];
GO
SELECT [Link], [Link], [Link]
INTO [Link]
FROM [Link] AS pp JOIN [Link] AS e
ON [Link] = [Link]
WHERE LastName = 'Johnson';
GO
SELECT [Link], [Link], [Link]
INTO [Link]
FROM [Link] AS pp JOIN [Link] AS e
ON [Link] = [Link]
WHERE LastName = 'Johnson';
GO
SELECT [Link], [Link], [Link]
INTO [Link]
FROM [Link] AS pp JOIN [Link] AS e
ON [Link] = [Link]
WHERE LastName = 'Johnson';
GO
-- Union ALL
SELECT LastName, FirstName, JobTitle
FROM [Link]
UNION ALL
SELECT LastName, FirstName ,JobTitle
FROM [Link]
UNION ALL
SELECT LastName, FirstName,JobTitle
FROM [Link];
P á g i n a 14 | 15
GO
SELECT LastName, FirstName,JobTitle
FROM [Link]
UNION
SELECT LastName, FirstName, JobTitle
FROM [Link]
UNION
SELECT LastName, FirstName, JobTitle
FROM [Link];
GO
SELECT LastName, FirstName,JobTitle
FROM [Link]
UNION ALL
(
SELECT LastName, FirstName, JobTitle
FROM [Link]
UNION
SELECT LastName, FirstName, JobTitle
FROM [Link]
);
GO
P á g i n a 15 | 15