Curso SQL · Northwind
Tema 2 de 64
Bloque 1 · Antes de escribir SQL PostgreSQL 17 northwind

El negocio de Northwind

1. Tu primer día

Ya estás dentro de la base. Ahora imagina que ese acceso es el de tu primer día como analista de datos en Northwind Traders.

Nadie te va a sentar a explicarte la empresa en detalle. Te darán cuatro frases sueltas —"vendemos comida importada, tenemos clientes en varios países"— y poco más. Pero te dan algo que vale muchísimo más que esa charla: el acceso a la base de datos.

Y ahí está todo. Una base de datos de empresa no guarda una muestra ni un resumen: guarda la historia completa de la operación. Cada pedido que entró, cada cliente que compró, cada producto que dejó de venderse. Nadie te va a contar ese negocio mejor de lo que te lo pueden contar sus propias tablas.

Aprender a leerlo es la habilidad. Un analista que solo escribe consultas devuelve números; uno que entiende el negocio detrás devuelve respuestas.

En este capítulo te damos el contexto ya masticado, y junto a cada dato, la consulta que lo saca. Ejecútalas: no se trata de que te creas los números, sino de que veas de dónde salen.

2. Qué es Northwind

Northwind Traders importa alimentos de especialidad de todo el mundo y los revende al por mayor.

Sus clientes no son personas: son tiendas gourmet, delicatessen y restaurantes que le compran para revender. Nunca vende al público final.

Es una intermediaria. No fabrica nada. Su negocio son dos cosas —tener el catálogo correcto y hacerlo llegar— y todo lo que encuentres en la base sale de esas dos.

Es también una empresa pequeña: nueve personas. No esperes millones de filas; son los datos de una operación de tamaño humano entre julio de 1996 y mayo de 1998.

Los datos son ficticios, pero el negocio que describen no tiene nada de raro: es una distribuidora normal, con sus proveedores, sus comerciales y sus pedidos.

3. El catálogo — qué vende

Northwind vende 77 productos repartidos en 8 categorías. De esos 77, 10 están descatalogados: siguen en el catálogo pero ya no se venden, así que los productos vivos son 67. Los compra a 29 proveedores repartidos en 16 países.

Las ocho categorías son Beverages, Condiments, Confections, Dairy Products, Grains/Cereals, Meat/Poultry, Produce y Seafood.

-- ¿Cuántos productos tiene el catálogo?
SELECT
    count(*) AS productos
FROM
    products;

-- ¿Cuántos están descatalogados?
SELECT
    count(*) AS descatalogados
FROM
    products
WHERE
    discontinued;

-- ¿En cuántas categorías se agrupan?
SELECT
    count(*) AS categorias
FROM
    categories;

-- ¿Y cuáles son?
SELECT
    category_name AS categoria
FROM
    categories
ORDER BY
    category_name;

-- ¿A cuántos proveedores les compra?
SELECT
    count(*) AS proveedores
FROM
    suppliers;

-- ¿De cuántos países distintos?
SELECT
    count(DISTINCT country) AS paises_de_proveedores
FROM
    suppliers;

4. Los clientes — a quién le vende

Tiene 91 clientes repartidos en 21 países y 69 ciudades. Los tres mercados más grandes son Estados Unidos con 13 clientes, y Francia y Alemania empatados con 11 cada uno.

-- ¿Cuántos clientes tiene?
SELECT
    count(*) AS clientes
FROM
    customers;

-- ¿En cuántos países hay clientes?
SELECT
    count(DISTINCT country) AS paises_de_clientes
FROM
    customers;

-- ¿Y en cuántas ciudades?
SELECT
    count(DISTINCT city) AS ciudades_de_clientes
FROM
    customers;

-- ¿Cuántos clientes hay en cada país?
SELECT
    country AS pais,
    count(*) AS clientes
FROM
    customers
GROUP BY
    country
ORDER BY
    clientes DESC;

5. La operación — cuánto ha vendido

En sus registros hay 830 pedidos, del 4 de julio de 1996 al 6 de mayo de 1998 — veintidós meses. En total facturó 1.265.793,04, lo que da un ticket medio de 1.525,05 por pedido.

-- ¿Cuántos pedidos ha procesado?
SELECT
    count(*) AS pedidos
FROM
    orders;

-- ¿Entre qué fechas?
SELECT
    min(order_date) AS primer_pedido,
    max(order_date) AS ultimo_pedido
FROM
    orders;

-- ¿Cuánto facturó en total?
SELECT
    sum(unit_price * quantity * (1 - discount)) AS facturacion
FROM
    order_details;

El ticket medio sale de dividir: 1.265.793,04 ÷ 830 = 1.525,05. La consulta que lo calcula sola necesita una subconsulta, y eso llega más adelante en el curso.

Fíjate de dónde sale la facturación: no está guardada en ninguna columna. Se calcula multiplicando precio por cantidad y restando el descuento, línea a línea. Es la primera señal de algo que verás mucho: en una base de datos de producción los importes suelen calcularse, no almacenarse.

6. La empresa — quiénes la llevan

Northwind la llevan 9 personas: un vicepresidente de ventas, un jefe de ventas, seis comerciales y una coordinadora interna.

No tiene camiones propios — subcontrata el transporte a 6 empresas. Y su fuerza de ventas cubre 53 territorios agrupados en 4 regiones: Eastern, Western, Northern y Southern.

-- ¿Cuánta gente trabaja aquí?
SELECT
    count(*) AS empleados
FROM
    employees;

-- ¿En qué puestos?
SELECT
    title AS cargo,
    count(*) AS cuantos
FROM
    employees
GROUP BY
    title
ORDER BY
    cuantos DESC;

-- ¿Con cuántos transportistas trabaja?
SELECT
    count(*) AS transportistas
FROM
    shippers;

-- ¿En cuántos territorios vende?
SELECT
    count(*) AS territorios
FROM
    territories;

-- ¿Y cómo se agrupan?
SELECT
    region_description AS region
FROM
    region
ORDER BY
    region_id;

7. Diferencias con SQL Server

discontinued es booleano, no un 0/1.

Northwind nació en SQL Server, donde esa columna es un entero. En esta base es boolean, así que la consulta que encontrarás en casi cualquier tutorial de internet falla aquí:

-- ❌ Esto revienta
SELECT
    count(*)
FROM
    products
WHERE
    discontinued = 1;
ERROR: operator does not exist: boolean = integer

La forma correcta en PostgreSQL no necesita comparar con nada, porque la columna ya es verdadero o falso:

-- ✅ Así sí
SELECT
    count(*)
FROM
    products
WHERE
    discontinued;

-- ✅ Equivalente, más explícito
SELECT
    count(*)
FROM
    products
WHERE
    discontinued IS TRUE;

-- ✅ Los que SÍ se venden
SELECT
    count(*)
FROM
    products
WHERE
    NOT discontinued;

Es el primer aviso de una regla que te va a acompañar todo el curso: una consulta copiada de internet puede estar escrita para otro motor. Cuando algo falle sin motivo aparente, la primera pregunta es ¿para qué base de datos se escribió esto?


Ya sabes para quién trabajas. Lo que viene ahora es mirar cómo están guardados esos datos por dentro — y a partir de aquí, cada tabla que abras será la de una empresa que entiendes, no un ejemplo abstracto.