Ruta SQL + Northwind
LÓGICA Y DATOS · SQL SERVER · NORTHWIND

Ruta práctica de SQL en 5 niveles

Una ruta interactiva para aprender y practicar T-SQL directamente desde el navegador, con laboratorios integrados en los cinco niveles y una versión acotada de Northwind.

5 niveles
7 tablas
1 script base
100% navegador
RUTA DE APRENDIZAJE

Cómo utilizar este curso

Revisa el modelo de datos y avanza nivel por nivel. Cada sección de ejercicios incorpora su propio laboratorio SQL y prepara Northwind Acotada automáticamente.

1

Comprende el modelo

Revisa las tablas, claves y relaciones de Northwind Acotada antes de comenzar las consultas.

2

Avanza por nivel

Estudia fundamentos y ejemplos. Luego entra a Ejercicios para abrir el laboratorio integrado del nivel.

3

Practica y verifica

Ejecuta SQL en el navegador, comprueba la estructura de tu solución y registra automáticamente tu progreso.

Mapa de la ruta

01 · SELECT y FROM02 · WHERE y ORDER BY03 · Funciones04 · JOIN05 · GROUP BY / HAVING
MODELO ENTIDAD–RELACIÓN

Northwind Acotada

El modelo conserva las entidades esenciales para practicar consultas relacionales sin cargar toda la Northwind tradicional.

Modelo entidad relación Northwind acotada

Haz clic sobre la imagen para ampliarla.

Nota de consistencia: la imagen BD funciona como referencia visual del modelo Northwind. El script de práctica incluido en esta guía es la fuente operativa para los laboratorios integrados y está aún más acotado: utiliza exactamente las 7 tablas y columnas descritas a continuación. En los ejercicios se usa OrderDetails (sin espacio).

Entidades del script de práctica

TablaClave primariaQué representaRelación principal
CategoriesCategoryIDClasificación de productosProducts.CategoryID
SuppliersSupplierIDProveedores de productosProducts.SupplierID
ProductsProductIDCatálogo, precio, stock y estadoOrderDetails.ProductID
CustomersCustomerIDClientes y localizaciónOrders.CustomerID
EmployeesEmployeeIDEmpleados responsables de pedidosOrders.EmployeeID
OrdersOrderIDCabecera del pedido, fechas y despachoOrderDetails.OrderID
OrderDetailsOrderID + ProductIDLíneas del pedido, cantidad, precio y descuentoOrders / Products

Relaciones 1 a muchos

Categories 1 → N Products Suppliers 1 → N Products Customers 1 → N Orders Employees 1 → N Orders Orders 1 → N OrderDetails Products 1 → N OrderDetails

OrderDetails tiene clave primaria compuesta por OrderID + ProductID. Eso evita repetir el mismo producto dos veces como una línea idéntica dentro de un pedido y, al mismo tiempo, conecta pedidos con productos.

BASE DE PRÁCTICA

Script Northwind Acotada

Los laboratorios cargan este script automáticamente. Aquí puedes revisarlo, copiarlo o descargarlo para utilizarlo también en un entorno SQL Server externo.

El script limpia tablas anteriores, crea las 7 tablas con PK/FK, inserta datos y deja consultas de verificación y ejemplo.

NIVEL 01

Fundamentos de SQL y primeras consultas

Modelo relacional, tablas, filas, columnas, claves y estructura SELECT / FROM.

Progreso del nivel
0%

¿Qué aprenderás?

Base de datos relacionalOrganiza la información en tablas relacionadas.
TablaConjunto de filas y columnas sobre una entidad: Customers, Products, Orders...
Clave primaria (PK)Identifica de manera única cada registro.
Clave foránea (FK)Conecta una tabla con la clave primaria de otra.
La estructura mínima de una consulta

SELECT indica qué columnas deseas ver y FROM indica desde qué tabla se obtienen.

SELECT ProductName, UnitPrice
FROM Products;

Paso 1: buscamos dos columnas. Paso 2: SQL Server lee la tabla Products. Paso 3: devuelve una fila por producto.

SELECT * versus columnas específicas

SELECT * es útil para explorar una tabla, pero en consultas reales conviene indicar las columnas que necesitas.

SELECT *
FROM Customers;

SELECT CompanyName, City, Country
FROM Customers;

Ejemplo 1 · Explorar clientes

SELECT CustomerID, CompanyName, City, Country
FROM Customers;
  1. Se consulta la tabla Customers.
  2. Se seleccionan cuatro columnas.
  3. Cada fila representa un cliente.

Ejemplo 2 · Ver catálogo de productos

SELECT ProductID, ProductName, UnitPrice, UnitsInStock
FROM Products;

Permite reconocer el identificador del producto, su nombre, precio y stock disponible.

Ejemplo 3 · Alias de salida

SELECT ProductName AS Producto,
       UnitPrice AS Precio
FROM Products;

El alias cambia el encabezado mostrado en el resultado; no modifica la estructura de la tabla.

🧪 LABORATORIO INTERACTIVO · NIVEL 01

Practica sin salir de Lógica y Datos

Selecciona una práctica. El curso prepara Northwind Acotada y abre el editor SQL Server integrado para este nivel.

Motor de ejecución: OneCompiler integrado en la página.
Editor disponible al entrar

Ejercicio 1 · Explorar categorías

Muestra todos los registros de la tabla Categories.

0 de 4 prácticas verificadas
0%

Uso seguro: utiliza únicamente datos ficticios de práctica. No ingreses contraseñas, claves API ni información confidencial.

Ejercicio 1. Muestra todos los registros de Categories.
Ver solución
SELECT * FROM Categories;
Ejercicio 2. Muestra nombre de empresa y país de todos los proveedores.
Ver solución
SELECT CompanyName, Country
FROM Suppliers;
Ejercicio 3. Lista nombre, apellido y cargo de los empleados.
Ver solución
SELECT FirstName, LastName, Title
FROM Employees;
Ejercicio 4. Muestra ID, fecha y país de destino de los pedidos.
Ver solución
SELECT OrderID, OrderDate, ShipCountry
FROM Orders;

Desafío final · Reconocer la base

Construye tres consultas distintas que permitan presentar: clientes, productos y pedidos. En cada consulta selecciona sólo las columnas que serían útiles en un reporte inicial.

Una posible solución
SELECT CustomerID, CompanyName, City, Country
FROM Customers;

SELECT ProductID, ProductName, UnitPrice, UnitsInStock
FROM Products;

SELECT OrderID, CustomerID, EmployeeID, OrderDate, ShipCountry
FROM Orders;
NIVEL 02

Filtrado, búsqueda y ordenamiento

WHERE, operadores, AND / OR / NOT, BETWEEN, LIKE, IN, TOP y ORDER BY.

Progreso del nivel
0%

Filtrar no es lo mismo que ordenar

WHERE decide qué filas participan en el resultado. ORDER BY decide en qué orden se muestran.

Comparación= <> > >= < <=
RangosBETWEEN incluye ambos extremos.
PatronesLIKE 'A%' busca valores que comienzan con A.
LógicaAND, OR, NOT combinan condiciones.
Orden lógico de una consulta básica
SELECT columnas
FROM tabla
WHERE condición
ORDER BY columna ASC;

Primero se identifica la tabla, luego se filtran las filas y finalmente se ordena el resultado.

Ejemplo 1 · Productos sobre $30

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice > 30
ORDER BY UnitPrice DESC;

Paso 1: seleccionamos nombre y precio. Paso 2: conservamos sólo precios sobre 30. Paso 3: mostramos primero los más caros.

Ejemplo 2 · Rango de precios

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice BETWEEN 15 AND 40
ORDER BY UnitPrice;

BETWEEN equivale conceptualmente a UnitPrice >= 15 AND UnitPrice <= 40.

Ejemplo 3 · Dos países

SELECT CompanyName, Country
FROM Customers
WHERE Country IN ('Germany', 'Brazil')
ORDER BY Country, CompanyName;

IN simplifica varios criterios de igualdad unidos con OR.

🧪 LABORATORIO INTERACTIVO · NIVEL 02

Practica sin salir de Lógica y Datos

Selecciona una práctica. El curso prepara Northwind Acotada y abre el editor SQL Server integrado para este nivel.

Motor de ejecución: OneCompiler integrado en la página.
Editor disponible al entrar

Ejercicio 1 · Clientes de Germany

Muestra CompanyName, City y Country de los clientes de Germany.

0 de 6 prácticas verificadas
0%

Uso seguro: utiliza únicamente datos ficticios de práctica. No ingreses contraseñas, claves API ni información confidencial.

Ejercicio 1. Clientes de Germany.
Ver solución
SELECT CompanyName, City, Country
FROM Customers
WHERE Country = 'Germany';
Ejercicio 2. Productos con stock menor o igual a 15.
Ver solución
SELECT ProductName, UnitsInStock
FROM Products
WHERE UnitsInStock <= 15;
Ejercicio 3. Productos activos con precio mayor a 20.
Ver solución
SELECT ProductName, UnitPrice, Discontinued
FROM Products
WHERE UnitPrice > 20 AND Discontinued = 0;
Ejercicio 4. Clientes cuyo nombre de empresa comienza con A.
Ver solución
SELECT CompanyName, Country
FROM Customers
WHERE CompanyName LIKE 'A%';
Ejercicio 5. Los 5 productos más caros.
Ver solución
SELECT TOP 5 ProductName, UnitPrice
FROM Products
ORDER BY UnitPrice DESC;
Ejercicio 6. Pedidos enviados a Brazil o Germany, ordenados por fecha.
Ver solución
SELECT OrderID, OrderDate, ShipCountry
FROM Orders
WHERE ShipCountry IN ('Brazil', 'Germany')
ORDER BY OrderDate;

Desafío final · Catálogo priorizado

Obtén los 7 productos activos de mayor precio que tengan stock disponible y precio igual o superior a 20.

Ver solución razonada
SELECT TOP 7
       ProductName,
       UnitPrice,
       UnitsInStock
FROM Products
WHERE Discontinued = 0
  AND UnitsInStock > 0
  AND UnitPrice >= 20
ORDER BY UnitPrice DESC;

El filtro elimina descontinuados y productos sin stock; TOP limita el resultado después de ordenar por precio descendente.

NIVEL 03

Funciones y columnas calculadas

Texto, números, fechas, conversión de tipos y expresiones calculadas.

Progreso del nivel
0%

Las funciones transforman la salida

En este nivel no necesitamos modificar los datos almacenados: usamos funciones para presentar, calcular o analizar información.

TextoUPPER, LOWER, LEN, CONCAT
NúmerosROUND y operaciones aritméticas.
FechasYEAR, MONTH, DAY, DATEDIFF.
ConversiónCAST y CONVERT.
Crear una columna calculada
SELECT ProductName,
       UnitPrice,
       UnitsInStock,
       UnitPrice * UnitsInStock AS ValorInventario
FROM Products;

La columna ValorInventario se calcula al ejecutar la consulta; no se guarda físicamente en Products.

Ejemplo 1 · Formatear nombres

SELECT CompanyName,
       UPPER(CompanyName) AS EmpresaMayuscula,
       LEN(CompanyName) AS LargoNombre
FROM Customers;

Dos funciones se aplican a la misma columna y generan salidas independientes.

Ejemplo 2 · Nombre completo del empleado

SELECT EmployeeID,
       CONCAT(FirstName, ' ', LastName) AS Empleado,
       Title
FROM Employees;

CONCAT combina valores de texto en una sola columna de salida.

Ejemplo 3 · Días hasta despacho

SELECT OrderID,
       OrderDate,
       ShippedDate,
       DATEDIFF(DAY, OrderDate, ShippedDate) AS DiasDespacho
FROM Orders
WHERE ShippedDate IS NOT NULL;

Se excluyen pedidos aún no despachados para evitar interpretar un NULL como una fecha.

🧪 LABORATORIO INTERACTIVO · NIVEL 03

Practica sin salir de Lógica y Datos

Selecciona una práctica. El curso prepara Northwind Acotada y abre el editor SQL Server integrado para este nivel.

Motor de ejecución: OneCompiler integrado en la página.
Editor disponible al entrar

Ejercicio 1 · Mayúsculas y longitud

Muestra ProductName en mayúsculas y la longitud de cada nombre.

0 de 6 prácticas verificadas
0%

Uso seguro: utiliza únicamente datos ficticios de práctica. No ingreses contraseñas, claves API ni información confidencial.

Ejercicio 1. Muestra el nombre de cada producto en mayúsculas y su longitud.
Ver solución
SELECT UPPER(ProductName) AS Producto,
       LEN(ProductName) AS Largo
FROM Products;
Ejercicio 2. Calcula el valor de inventario de cada producto.
Ver solución
SELECT ProductName,
       UnitPrice,
       UnitsInStock,
       UnitPrice * UnitsInStock AS ValorInventario
FROM Products;
Ejercicio 3. Redondea los precios a cero decimales.
Ver solución
SELECT ProductName,
       UnitPrice,
       ROUND(UnitPrice, 0) AS PrecioRedondeado
FROM Products;
Ejercicio 4. Separa año y mes de los pedidos.
Ver solución
SELECT OrderID,
       YEAR(OrderDate) AS Anio,
       MONTH(OrderDate) AS Mes
FROM Orders;
Ejercicio 5. Presenta la fecha del pedido como texto dd/mm/yyyy.
Ver solución
SELECT OrderID,
       CONVERT(VARCHAR(10), OrderDate, 103) AS FechaPedido
FROM Orders;
Ejercicio 6. Calcula el total bruto de cada línea de pedido.
Ver solución
SELECT OrderID,
       ProductID,
       Quantity,
       UnitPrice,
       Quantity * UnitPrice AS TotalBruto
FROM OrderDetails;

Desafío final · Valor del inventario

Genera un reporte con producto en mayúsculas, precio, precio redondeado, stock y valor de inventario. Incluye sólo productos con stock y ordena de mayor a menor valor.

Ver solución
SELECT UPPER(ProductName) AS Producto,
       UnitPrice AS Precio,
       ROUND(UnitPrice, 0) AS PrecioRedondeado,
       UnitsInStock AS Stock,
       UnitPrice * UnitsInStock AS ValorInventario
FROM Products
WHERE UnitsInStock > 0
ORDER BY ValorInventario DESC;
NIVEL 04

Consultas de múltiples tablas

PK/FK, INNER JOIN, LEFT JOIN, alias, joins múltiples, UNION y UNION ALL.

Progreso del nivel
0%

Relacionar datos

Northwind separa clientes, pedidos, empleados, productos y detalles. Las claves permiten reconstruir una vista de negocio sin duplicar información en una sola tabla.

Customers1 → NOrders1 → NOrderDetailsN ← 1Products
INNER JOIN

Devuelve filas que tienen coincidencia en ambas tablas.

SELECT o.OrderID, c.CompanyName, o.OrderDate
FROM Orders AS o
INNER JOIN Customers AS c
    ON o.CustomerID = c.CustomerID;
LEFT JOIN

Mantiene todas las filas de la tabla izquierda aunque no exista coincidencia a la derecha. En esta base es ideal para detectar clientes sin pedidos.

Ejemplo 1 · Pedido + cliente

SELECT o.OrderID,
       o.OrderDate,
       c.CompanyName AS Cliente
FROM Orders AS o
INNER JOIN Customers AS c
    ON o.CustomerID = c.CustomerID
ORDER BY o.OrderDate;

La FK Orders.CustomerID se compara con la PK Customers.CustomerID.

Ejemplo 2 · Pedido + cliente + empleado

SELECT o.OrderID,
       c.CompanyName AS Cliente,
       CONCAT(e.FirstName, ' ', e.LastName) AS Empleado
FROM Orders AS o
INNER JOIN Customers AS c
    ON o.CustomerID = c.CustomerID
INNER JOIN Employees AS e
    ON o.EmployeeID = e.EmployeeID;

Dos relaciones permiten mostrar quién compró y qué empleado gestionó el pedido.

Ejemplo 3 · Producto vendido por pedido

SELECT od.OrderID,
       p.ProductName,
       od.Quantity,
       od.UnitPrice,
       od.Quantity * od.UnitPrice AS Subtotal
FROM OrderDetails AS od
INNER JOIN Products AS p
    ON od.ProductID = p.ProductID;

OrderDetails actúa como tabla puente entre Orders y Products.

🧪 LABORATORIO INTERACTIVO · NIVEL 04

Practica sin salir de Lógica y Datos

Selecciona una práctica. El curso prepara Northwind Acotada y abre el editor SQL Server integrado para este nivel.

Motor de ejecución: OneCompiler integrado en la página.
Editor disponible al entrar

Ejercicio 1 · Pedido + cliente

Lista cada OrderID con CompanyName del cliente.

0 de 6 prácticas verificadas
0%

Uso seguro: utiliza únicamente datos ficticios de práctica. No ingreses contraseñas, claves API ni información confidencial.

Ejercicio 1. Lista cada pedido con el nombre del cliente.
Ver solución
SELECT o.OrderID, c.CompanyName
FROM Orders o
INNER JOIN Customers c
    ON o.CustomerID = c.CustomerID;
Ejercicio 2. Lista productos y su categoría.
Ver solución
SELECT p.ProductName, c.CategoryName
FROM Products p
INNER JOIN Categories c
    ON p.CategoryID = c.CategoryID;
Ejercicio 3. Lista productos y proveedor.
Ver solución
SELECT p.ProductName, s.CompanyName AS Proveedor
FROM Products p
INNER JOIN Suppliers s
    ON p.SupplierID = s.SupplierID;
Ejercicio 4. Muestra todos los clientes, tengan o no pedidos.
Ver solución
SELECT c.CustomerID, c.CompanyName, o.OrderID
FROM Customers c
LEFT JOIN Orders o
    ON c.CustomerID = o.CustomerID;
Ejercicio 5. Detecta clientes sin pedidos.
Ver solución
SELECT c.CustomerID, c.CompanyName
FROM Customers c
LEFT JOIN Orders o
    ON c.CustomerID = o.CustomerID
WHERE o.OrderID IS NULL;
Ejercicio 6. Combina ciudades de clientes y proveedores sin duplicados.
Ver solución
SELECT City, Country
FROM Customers
UNION
SELECT NULL AS City, Country
FROM Suppliers
ORDER BY Country, City;

La tabla Suppliers acotada no tiene columna City; se usa NULL para mantener dos columnas compatibles y conservar el ejemplo de UNION.

Desafío final · Detalle completo de ventas

Construye una consulta que muestre pedido, fecha, cliente, empleado, producto, cantidad, precio unitario y total bruto de línea.

Ver solución
SELECT o.OrderID,
       o.OrderDate,
       c.CompanyName AS Cliente,
       CONCAT(e.FirstName, ' ', e.LastName) AS Empleado,
       p.ProductName AS Producto,
       od.Quantity,
       od.UnitPrice,
       od.Quantity * od.UnitPrice AS TotalBruto
FROM Orders o
INNER JOIN Customers c
    ON o.CustomerID = c.CustomerID
INNER JOIN Employees e
    ON o.EmployeeID = e.EmployeeID
INNER JOIN OrderDetails od
    ON o.OrderID = od.OrderID
INNER JOIN Products p
    ON od.ProductID = p.ProductID
ORDER BY o.OrderID, p.ProductName;
NIVEL 05

Agrupamiento y reportes

COUNT, SUM, AVG, MIN, MAX, DISTINCT, GROUP BY, HAVING y reportes con JOIN.

Progreso del nivel
0%

De registros a indicadores

Las funciones agregadas resumen muchas filas en uno o varios resultados. GROUP BY define el nivel de agrupación y HAVING filtra grupos ya calculados.

COUNTCuenta filas o valores.
SUM / AVGSuma y promedio.
MIN / MAXValores mínimo y máximo.
DISTINCTElimina duplicados de la salida.
WHERE y HAVING: diferencia esencial

WHERE filtra filas antes de agrupar. HAVING filtra el resultado de los grupos.

SELECT ShipCountry, COUNT(*) AS TotalPedidos
FROM Orders
GROUP BY ShipCountry
HAVING COUNT(*) >= 2
ORDER BY TotalPedidos DESC;
Sobre importación/exportación: tus materiales originales incluyen esta materia para SQL Server Management Studio. En OneCompiler nos enfocamos en consultas SQL; la importación/exportación mediante asistentes de SSMS se mantiene como contenido del entorno local y no como práctica web.

Ejemplo 1 · Clientes por país

SELECT Country,
       COUNT(*) AS TotalClientes
FROM Customers
GROUP BY Country
ORDER BY TotalClientes DESC;

Cada país forma un grupo y COUNT(*) calcula cuántos clientes contiene.

Ejemplo 2 · Total vendido por pedido con descuento

SELECT OrderID,
       SUM(Quantity * UnitPrice * (1 - Discount)) AS TotalPedido
FROM OrderDetails
GROUP BY OrderID
ORDER BY TotalPedido DESC;

La expresión se calcula por línea y luego SUM consolida todas las líneas del mismo pedido.

Ejemplo 3 · Ventas por cliente

SELECT c.CompanyName AS Cliente,
       SUM(od.Quantity * od.UnitPrice * (1 - od.Discount)) AS TotalVendido
FROM Customers c
INNER JOIN Orders o
    ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od
    ON o.OrderID = od.OrderID
GROUP BY c.CompanyName
ORDER BY TotalVendido DESC;

El JOIN identifica a quién pertenece cada pedido; luego el agrupamiento consolida las ventas por cliente.

🧪 LABORATORIO INTERACTIVO · NIVEL 05

Practica sin salir de Lógica y Datos

Selecciona una práctica. El curso prepara Northwind Acotada y abre el editor SQL Server integrado para este nivel.

Motor de ejecución: OneCompiler integrado en la página.
Editor disponible al entrar

Ejercicio 1 · Total de productos

Cuenta los registros de Products.

0 de 7 prácticas verificadas
0%

Uso seguro: utiliza únicamente datos ficticios de práctica. No ingreses contraseñas, claves API ni información confidencial.

Ejercicio 1. Cuenta los productos.
Ver solución
SELECT COUNT(*) AS TotalProductos
FROM Products;
Ejercicio 2. Calcula precio mínimo, máximo y promedio.
Ver solución
SELECT MIN(UnitPrice) AS Minimo,
       MAX(UnitPrice) AS Maximo,
       AVG(UnitPrice) AS Promedio
FROM Products;
Ejercicio 3. Lista los países distintos de clientes.
Ver solución
SELECT DISTINCT Country
FROM Customers
ORDER BY Country;
Ejercicio 4. Cuenta productos por categoría.
Ver solución
SELECT c.CategoryName,
       COUNT(p.ProductID) AS TotalProductos
FROM Categories c
LEFT JOIN Products p
    ON c.CategoryID = p.CategoryID
GROUP BY c.CategoryName
ORDER BY TotalProductos DESC;
Ejercicio 5. Cuenta pedidos gestionados por empleado.
Ver solución
SELECT CONCAT(e.FirstName, ' ', e.LastName) AS Empleado,
       COUNT(o.OrderID) AS TotalPedidos
FROM Employees e
LEFT JOIN Orders o
    ON e.EmployeeID = o.EmployeeID
GROUP BY e.FirstName, e.LastName
ORDER BY TotalPedidos DESC;
Ejercicio 6. Muestra sólo países de envío con 2 o más pedidos.
Ver solución
SELECT ShipCountry,
       COUNT(*) AS TotalPedidos
FROM Orders
GROUP BY ShipCountry
HAVING COUNT(*) >= 2
ORDER BY TotalPedidos DESC;
Ejercicio 7. Total vendido por producto considerando descuento.
Ver solución
SELECT p.ProductName,
       SUM(od.Quantity * od.UnitPrice * (1 - od.Discount)) AS TotalVendido
FROM Products p
INNER JOIN OrderDetails od
    ON p.ProductID = od.ProductID
GROUP BY p.ProductName
ORDER BY TotalVendido DESC;

Desafío final · Reporte ejecutivo de clientes

Para cada cliente que tenga pedidos, muestra país, cantidad de pedidos, total neto vendido y ticket promedio por línea. Ordena por venta total descendente.

Ver solución
SELECT c.CompanyName AS Cliente,
       c.Country AS Pais,
       COUNT(DISTINCT o.OrderID) AS TotalPedidos,
       SUM(od.Quantity * od.UnitPrice * (1 - od.Discount)) AS TotalVendido,
       AVG(od.Quantity * od.UnitPrice * (1 - od.Discount)) AS PromedioLinea
FROM Customers c
INNER JOIN Orders o
    ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od
    ON o.OrderID = od.OrderID
GROUP BY c.CompanyName, c.Country
ORDER BY TotalVendido DESC;