(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo crear una tabla de historial de precios en Data Warehouse: paso a paso

João Barros 18 de October de 2026 4 min de lectura

Este tutorial muestra cómo crear una tabla de historial de precios en Data Warehouse para registrar cambios de precio de productos a lo largo del tiempo. Tener un historial de precios permite análisis temporales, calcular tendencias y reconstruir precios válidos para cualquier fecha.

Requisitos previos

  • Conocimientos básicos de SQL (SELECT, INSERT, UPDATE)
  • Entorno Data Warehouse con soporte SQL (p.ej.: Azure Synapse, SQL Server, Snowflake)
  • Tabla de origen de productos con identificador y precio actual
  • Permisos para crear tablas y triggers/procedures (o procesos ETL)

Paso 1: Elegir el modelo de historial (SCD vs timeline)

Hay dos enfoques comunes: usar SCD Tipo 2 (registros con date_effective/date_end y flag activo) o mantener una tabla de eventos de precio (cada cambio es un evento). Para historial de precios simple y consultas por fecha, el patrón SCD Tipo 2 o una timeline con date_effective es ideal. Aquí usamos una timeline con date_effective y date_end para consultas sencillas.

Paso 2: Crear la tabla de historial de precios

Crear la tabla que almacenará versiones de precio. Mantenemos campos esenciales: product_id, price, currency, date_effective (inicio de validez), date_end (fin de validez, NULL si actual), is_current.

CREATE TABLE price_history (
  price_history_id BIGINT IDENTITY(1,1) PRIMARY KEY,
  product_id INT NOT NULL,
  price DECIMAL(18,4) NOT NULL,
  currency VARCHAR(3) NOT NULL DEFAULT 'EUR',
  date_effective DATE NOT NULL,
  date_end DATE NULL,
  is_current BIT NOT NULL DEFAULT 1,
  created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
);

Paso 3: Población inicial desde la tabla de productos

Copie el estado actual de los precios a price_history con date_effective igual a la fecha de carga. Este paso garantiza que existe al menos un registro por producto.

INSERT INTO price_history (product_id, price, currency, date_effective, date_end, is_current)
SELECT p.product_id, p.price, p.currency, CAST(GETDATE() AS DATE), NULL, 1
FROM products p
WHERE p.price IS NOT NULL;

Paso 4: Procesar cambios de precio (ETL o trigger)

Cuando llega una nueva carga de precios (feed diario o evento), compare con price_history y cierre registros antiguos antes de insertar el nuevo. Abajo un ejemplo ETL en SQL que procesa la tabla staging_prices con los precios más recientes.

-- 1) Encontrar productos con cambio de precio
WITH changes AS (
  SELECT s.product_id, s.price, s.currency
  FROM staging_prices s
  JOIN price_history ph ON ph.product_id = s.product_id AND ph.is_current = 1
  WHERE ph.price <> s.price OR ph.currency <> s.currency
)
-- 2) Cierra los registros actuales, estableciendo date_end e is_current = 0
UPDATE ph
SET ph.date_end = CAST(GETDATE() AS DATE), ph.is_current = 0
FROM price_history ph
JOIN changes c ON ph.product_id = c.product_id
WHERE ph.is_current = 1;

-- 3) Inserta nuevos registros con la nueva validez
INSERT INTO price_history (product_id, price, currency, date_effective, date_end, is_current)
SELECT c.product_id, c.price, c.currency, CAST(GETDATE() AS DATE), NULL, 1
FROM changes c;

Paso 5: Consultas comunes y optimizaciones

Consulta del precio válido en una fecha, agregaciones de tendencia e índices para rendimiento. Cree índice por (product_id, is_current) y por (product_id, date_effective, date_end) si hay muchas búsquedas históricas.

-- Precio actual por producto
SELECT product_id, price
FROM price_history
WHERE product_id = 123 AND is_current = 1;

-- Precio válido en una fecha específica
SELECT price
FROM price_history
WHERE product_id = 123
  AND date_effective <= '2026-10-01'
  AND (date_end IS NULL OR date_end >= '2026-10-01');

-- Índice sugerido (SQL Server example)
CREATE INDEX IX_price_history_product_current ON price_history(product_id, is_current);

Verificar el resultado

Confirme que cada producto tiene exactamente un registro con is_current = 1 (si existe precio actual) y que los registros antiguos tienen date_end relleno. Ejecute muestras de consultas por fecha para validar valores históricos. Ejemplos:

-- Verificar unicity current
SELECT product_id, COUNT(*) as cnt
FROM price_history
WHERE is_current = 1
GROUP BY product_id
HAVING COUNT(*) > 1;

-- Verificar productos sin registro
SELECT p.product_id
FROM products p
LEFT JOIN price_history ph ON p.product_id = ph.product_id
WHERE ph.price_history_id IS NULL;

Conclusión

Una tabla de historial de precios bien diseñada permite análisis temporales y consistencia en los informes. Próximos pasos: automatizar el proceso ETL, gestionar fusiones de productos y administrar reglas de moneda. Consejo: probar el flujo con datos reales y comprobar edge cases como cambios múltiples en el mismo día.