¿Por qué son útiles las líneas de tiempo en el análisis de datos?
Las líneas de tiempo resultan ser una herramienta indispensable para el análisis de datos al permitir visualizar de manera clara y ordenada eventos a lo largo del tiempo. A través de ellas, podemos identificar fácilmente picos de actividad, tendencias y variaciones que ofrecen un contexto significativo sobre el comportamiento de ciertos datos. Estos insights nos guían en la toma de decisiones más inteligentes basadas en cómo han cambiado las métricas a lo largo del tiempo.
¿Cómo interpretar las tendencias en una línea de tiempo?
Una línea de tiempo nos permite identificar tendencias mediante el análisis de la dirección de la pendiente que se forma al unir los puntos de datos. Si la línea muestra un ascenso hacia arriba, indicaría que la variable analizada está aumentando. Por ejemplo, cuando las ventas de una empresa aumentan, la línea de tiempo lo reflejará con esta tendencia hacia arriba. Por el contrario, una tendencia hacia abajo indicaría una disminución. Es crucial también considerar el contexto, ya que, por ejemplo, en costos empresariales, un descenso en la línea de tiempo podría ser algo positivo.
¿Qué aspectos técnicos son relevantes al crear una línea de tiempo en SQL?
Para construir una línea de tiempo, lo primero que necesitamos es un campo de datos temporal, como una fecha, de donde extraeremos los componentes importantes como el año y el mes. En SQL, podemos utilizar funciones como DATE_PART para desglosar las fechas y seleccionar los fragmentos de tiempo necesarios. Además, comúnmente necesitaremos realizar un conteo y agrupar los datos según el año y mes para obtener una representación más estructurada.
Aquí un ejemplo de cómo se realiza la selección y agrupación en SQL:
SELECT DATE_PART('year', rentas.fecha_renta)AS año, DATE_PART('month', rentas.fecha_renta)AS mes,COUNT(*)AS numero_rentas
FROM rentas
GROUPBY año, mes
ORDERBY año, mes;
¿Cuál es la importancia de los "JOIN" al consultar múltiples tablas?
Cuando se necesita información de múltiples tablas, el uso de "JOIN" es fundamental para enlazar los datos correctamente. Esto permite un acceso más estructurado y detallado a los datos, asegurando que las relaciones entre los distintos objetos de datos se mantengan intactas. Un ejemplo de aplicación es cuando quieres correlacionar películas con sus rentas a través de identificadores comunes.
FROM rentas
JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
¿Qué nos dice el conteo de rentas a lo largo del tiempo?
Analizar el número de rentas mediante líneas de tiempo permite entender patrones de consumo, como estacionalidades y periodos de mayor o menor demanda. Estos patrones ofrecen una base sólida para planificar estrategias empresariales, como promociones o producción de inventario, ajustándose a las tendencias y previsiones del mercado.
Ejemplo práctico
Consideremos los datos de rentas de películas. Si observamos que una determinada película tiene un alto número de rentas en diciembre, podría ser ventajoso enfocar promociones o estrategias de marketing durante esta época. Contraposición, otras películas podrían seguir patrones diferentes, como picos en períodos de vacaciones de verano, ayudando a gestionar recursos y decisiones de inventario de manera más eficaz.
¡Examina cómo las líneas de tiempo pueden transformar la forma en que se interpretan los datos y te animo a poner en práctica este enfoque con diferentes conjuntos de datos para obtener análisis más enriquecedores!
Algo no me cuadraba haciendo queries de los pagos, así que hice esto y me di cuenta que la gente paga 2 años después de rentar las películas. Qué buen servicio.
Tengo la impresión, que la generación de estos datos (no se me ocurre otra cosa que explique la falta de sentido de los datos) no se realizó con el debido cuidado, y casi seguro estoy que estos datos no son reales, osea, no son tomados (pienso que anónimamente) de datos de alguna empresa real.
Comparto estos dos querys trabajando con la tabla de pagos de la DB platzi_movies
--Cant de pagos por año, mes, costos percibidos y película
SELECTdate_part('year', pagos.fecha_pago)AS anio,date_part('month', pagos.fecha_pago)AS mes,COUNT(*)ASCant_pagos,SUM(cantidad)ASCant_$_Rentas, peliculas.tituloFROM pagos
INNERJOIN rentas ON rentas.renta_id= pagos.renta_idINNERJOIN inventarios ON inventarios.inventario_id= rentas.inventario_idINNERJOIN peliculas ON inventarios.pelicula_id= peliculas.pelicula_idGROUPBY peliculas.titulo, anio, mes
ORDERBY cant_pagos DESC;--Cant de pagos por año, mes, costos percibidos
SELECTdate_part('year', pagos.fecha_pago)AS anio,date_part('month', pagos.fecha_pago)AS mes,COUNT(*)ASCant_pagos,SUM(cantidad)ASCant_$_RentasFROM pagos
GROUPBY anio, mes
ORDERBY anio, mes, cant_pagos DESC;```
Hice una consulta para sacar la Cantidad de pagos mensuales.
SELECT
EXTRACT(YEAR FROM fecha_pago) as anio,
EXTRACT(MONTH FROM fecha_pago) as mes,
SUM(cantidad) as total_pago_mensual
FROM pagos
group by anio, mes
order by anio asc ,mes asc
Está clase fue muy útil a pesar que la consulta era muy sencilla.
Me quedo claro como darle siginificado a los datos a traves del tiempo asignando alguna categora para sumergirse mas en el comportamiento en este caso del mercado de rentas de películas.
Tal como escribí antes, hay gente que rentó una película y no la pagó. Me puse a buscar quienes fueron las personas que hicieron esta "gracia" y aquí la lista.
Trabajar con datos en el tiempo en bases de datos relacionales, como PostgreSQL, implica la gestión y análisis de valores que cambian o están asociados con una dimensión temporal. Esto es esencial para analizar tendencias, calcular valores históricos, realizar predicciones o comparar periodos.
A continuación, te explico cómo gestionar y analizar datos temporales, con ejemplos prácticos en PostgreSQL:
1. Tipos de datos temporales
En PostgreSQL, los principales tipos de datos para manejar tiempo son:
DATE: Solo almacena la fecha (ej. 2025-01-24).
TIME: Solo almacena la hora (ej. 14:30:00).
TIMESTAMP: Fecha y hora sin zona horaria (ej. 2025-01-24 14:30:00).
TIMESTAMPTZ: Fecha y hora con zona horaria (ej. 2025-01-24 14:30:00+00).
INTERVAL: Representa una duración (ej. 2 days 3 hours).
2. Insertar y almacenar datos temporales
Ejemplo
Supongamos que tienes una tabla ventas para almacenar transacciones con una marca temporal:
CREATE TABLE ventas (
id SERIAL PRIMARY KEY,
producto VARCHAR(100),
cantidad INT,
precio DECIMAL(10, 2),
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
La columna fecha almacena el momento en que se realiza la venta.
Insertar un registro:
INSERT INTO ventas (producto, cantidad, precio)
VALUES ('Laptop', 1, 2500.00);
3. Consultas temporales comunes
a) Filtrar por rango de fechas
Para encontrar ventas realizadas en un rango de fechas:
SELECT *
FROM ventas
WHERE fecha BETWEEN '2025-01-01' AND '2025-01-24';
b) Filtrar por periodos específicos
Ventas realizadas en un mes en particular:
SELECT *
FROM ventas
WHERE EXTRACT(MONTH FROM fecha) = 1 AND EXTRACT(YEAR FROM fecha) = 2025;
4. Agregaciones temporales
a) Agrupar por día
Sumar ventas por día:
SELECT DATE(fecha) AS dia, SUM(precio * cantidad) AS total_ventas
FROM ventas
GROUP BY DATE(fecha)
ORDER BY dia;
b) Agrupar por mes
SELECT DATE_TRUNC('month', fecha) AS mes, SUM(precio * cantidad) AS total_ventas
FROM ventas
GROUP BY DATE_TRUNC('month', fecha)
ORDER BY mes;
DATE_TRUNC: Trunca la fecha al inicio del mes, año, día, etc.
5. Calcular diferencias en el tiempo
a) Tiempo transcurrido entre eventos
Si necesitas calcular la diferencia entre fechas (por ejemplo, entre ventas):
SELECT id, producto, fecha,
fecha - LAG(fecha) OVER (ORDER BY fecha) AS tiempo_desde_ultima_venta
FROM ventas;
LAG: Devuelve el valor de la fila anterior dentro de la ventana.
b) Diferencias absolutas
Duración total entre dos fechas específicas:
SELECT '2025-01-24'::DATE - '2025-01-01'::DATE AS dias_transcurridos;
6. Funciones temporales útiles
a) Fecha actual
SELECT CURRENT_DATE; -- Solo la fecha actual
SELECT CURRENT_TIMESTAMP; -- Fecha y hora actual
b) Extraer partes de la fecha
SELECT EXTRACT(YEAR FROM fecha) AS anio,
EXTRACT(MONTH FROM fecha) AS mes,
EXTRACT(DAY FROM fecha) AS dia
FROM ventas;
c) Agregar o restar tiempo
Sumar o restar intervalos a una fecha:
SELECT fecha + INTERVAL '1 day' AS manana,
fecha - INTERVAL '7 days' AS semana_pasada
FROM ventas;
7. Consultas avanzadas
a) Ventas acumuladas
Para calcular el total acumulado de ventas a lo largo del tiempo:
SELECT fecha,
SUM(precio * cantidad) OVER (ORDER BY fecha) AS ventas_acumuladas
FROM ventas;
b) Ventas promedio móviles
Para calcular un promedio móvil de 7 días:
SELECT fecha,
AVG(precio * cantidad) OVER (ORDER BY fecha ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS promedio_movil
FROM ventas;
8. Indexación temporal
Para mejorar el rendimiento de consultas basadas en fechas, puedes crear índices:
CREATE INDEX idx_fecha ON ventas (fecha);
9. Aplicaciones comunes de datos temporales
Análisis de tendencias: Identificar patrones de venta por días, semanas o meses.
Predicciones: Basadas en datos históricos para anticipar futuras ventas o eventos.
Alertas: Detectar retrasos o anomalías al monitorear eventos en tiempo real.
Tal como mencionó alguien, después de rentar la película la gente paga de 400 a casi 700 días después, y aún más, hubo gente que rentó las películas y nunca las pagó.
(
Al ver la importancia de las líneas de tiempo para identificar patrones (como estacionalidades en las rentas), me surge una duda al aplicar esto en la práctica: ¿Cómo podemos determinar la granularidad de tiempo (año, mes, día, etc.) más adecuada en nuestro query de SQL, cuando estamos empezando un análisis y aún no conocemos bien la volatilidad del conjunto de datos? ¿Existe alguna regla general o estrategia inicial para elegir el DATE_PART correcto que evite tanto el ruido excesivo como la pérdida de tendencias importantes?"
/*
Datos por temporalidad
Tiendas (y sus direcciones) más activas por año y por mes
*/SELECTEXTRACT('YEAR'FROM direcciones.ultima_actualizacion)AS anio_actividad,EXTRACT('MONTH'FROM direcciones.ultima_actualizacion)AS mes_actividad, direcciones.direccion_id, direcciones.direccion,COUNT(renta_id)AS cantidad_rentas
FROM direcciones
JOIN tiendas ON tiendas.direccion_id= direcciones.direccion_idJOIN inventarios ON inventarios.tienda_id= tiendas.tienda_idJOIN rentas ON rentas.inventario_id= inventarios.inventario_idGROUPBY direcciones.direccion_id, direcciones.direccionORDERBY cantidad_rentas DESC
Una variante
--Pagos promedio, alquileres únicos y porcentajes
SELECTdate_part('year', p.fecha_pago)AS anio,date_part('month', p.fecha_pago)AS mes, pel.titulo,COUNT(*)AS cant_pagos,SUM(p.cantidad)AS total_rentas,-- métricas de comparación
SUM(SUM(p.cantidad))OVER(PARTITIONBYdate_part('year', p.fecha_pago),date_part('month', p.fecha_pago))AS total_mensual,ROUND((SUM(p.cantidad)*100.0/SUM(SUM(p.cantidad))OVER(PARTITIONBYdate_part('year', p.fecha_pago),date_part('month', p.fecha_pago))),2)AS porcentaje_mensual
FROM pagos p
INNERJOIN rentas r ON r.renta_id= p.renta_idINNERJOIN inventarios i ON i.inventario_id= r.inventario_idINNERJOIN peliculas pel ON i.pelicula_id= pel.pelicula_idGROUPBY anio, mes, pel.tituloORDERBY anio, mes, total_rentas DESC;