¡Ahora sí, estás listo para sumergirte en el mundo de los ejemplos prácticos y ver cómo funciona todo esto en problemas reales!
Ejemplo: cálculo del ranking de ventas por regiones
Imagina que tenemos una tabla sales con datos de ventas en diferentes regiones. Necesitamos determinar el ranking de ventas para cada región.
| id | region | sales_amount |
|---|---|---|
| 1 | North | 5000 |
| 2 | North | 3000 |
| 3 | North | 7000 |
| 4 | South | 2000 |
| 5 | South | 4000 |
| 6 | East | 8000 |
| 7 | East | 6000 |
Objetivo: encontrar el ranking (RANK) de ventas por cada región
SELECT
region,
sales_amount,
RANK() OVER (PARTITION BY region ORDER BY sales_amount DESC) AS sales_rank
FROM
sales;
Resultado:
| region | sales_amount | sales_rank |
|---|---|---|
| North | 7000 | 1 |
| North | 5000 | 2 |
| North | 3000 | 3 |
| South | 4000 | 1 |
| South | 2000 | 2 |
| East | 8000 | 1 |
| East | 6000 | 2 |
Fíjate que usamos PARTITION BY region para calcular el ranking por separado para cada región. Si no usáramos PARTITION BY, el ranking sería global para toda la tabla.
Ejemplo: cálculo de suma acumulada de ingresos
Ahora vamos a trabajar con la tabla transactions para calcular la suma acumulada de ingresos para cada cliente.
| id | customer_id | purchase_date | amount |
|---|---|---|---|
| 1 | 101 | 2023-01-01 | 100 |
| 2 | 101 | 2023-01-03 | 50 |
| 3 | 102 | 2023-01-02 | 200 |
| 4 | 101 | 2023-01-05 | 150 |
| 5 | 102 | 2023-01-04 | 100 |
Objetivo: calcular la suma acumulada para cada cliente
SELECT
customer_id,
purchase_date,
amount,
SUM(amount) OVER (PARTITION BY customer_id ORDER BY purchase_date) AS cumulative_sum
FROM
transactions;
Resultado:
| customer_id | purchase_date | amount | cumulative_sum |
|---|---|---|---|
| 101 | 2023-01-01 | 100 | 100 |
| 101 | 2023-01-03 | 50 | 150 |
| 101 | 2023-01-05 | 150 | 300 |
| 102 | 2023-01-02 | 200 | 200 |
| 102 | 2023-01-04 | 100 | 300 |
El truco aquí es usar ORDER BY purchase_date dentro de OVER() para que la suma acumulada se calcule en orden cronológico.
Ejemplo: partición de datos en cuantiles
Imagina que tenemos una tabla students con nombres y resultados de tests. Queremos dividir a los estudiantes en 4 grupos según sus resultados.
| id | name | test_score |
|---|---|---|
| 1 | Alice | 85 |
| 2 | Bob | 95 |
| 3 | Charlie | 75 |
| 4 | Diana | 88 |
| 5 | Edward | 65 |
| 6 | Fiona | 70 |
Objetivo: dividir a los estudiantes en 4 grupos usando NTILE()
SELECT
name,
test_score,
NTILE(4) OVER (ORDER BY test_score DESC) AS quartile
FROM
students;
El resultado de la consulta será así:
| name | test_score | quartile |
|---|---|---|
| Bob | 95 | 1 |
| Diana | 88 | 1 |
| Alice | 85 | 2 |
| Charlie | 75 | 3 |
| Fiona | 70 | 3 |
| Edward | 65 | 4 |
NTILE(4) divide los datos en 4 grupos. Los estudiantes con las notas más altas caen en el primer grupo, y los de notas más bajas en el último.
Ejemplo: análisis de datos temporales
En la tabla site_visits tenemos datos sobre el número de visitas al sitio por día. Necesitamos calcular la diferencia de visitas entre días para cada sitio.
| site_id | visit_date | visits |
|---|---|---|
| 1 | 2023-01-01 | 100 |
| 1 | 2023-01-02 | 120 |
| 1 | 2023-01-03 | 110 |
| 2 | 2023-01-01 | 50 |
| 2 | 2023-01-02 | 60 |
| 2 | 2023-01-03 | 70 |
Nuestro objetivo es calcular la diferencia de visitas entre días
SELECT
site_id,
visit_date,
visits,
visits - LAG(visits) OVER (PARTITION BY site_id ORDER BY visit_date) AS visit_diff
FROM
site_visits;
Resultado:
| site_id | visit_date | visits | visit_diff |
|---|---|---|---|
| 1 | 2023-01-01 | 100 | NULL |
| 1 | 2023-01-02 | 120 | 20 |
| 1 | 2023-01-03 | 110 | -10 |
| 2 | 2023-01-01 | 50 | NULL |
| 2 | 2023-01-02 | 60 | 10 |
| 2 | 2023-01-03 | 70 | 10 |
La función LAG() te deja pillar el valor de la fila anterior. Si no hay datos para la fila anterior, el resultado será NULL. Ya verás más sobre esto en las siguientes lecciones :P
GO TO FULL VERSION