The actualizacion table maintains a complete audit trail of all price changes for products. Each record captures the previous price, new price, timestamp, and the employee who authorized the change. This ensures price transparency and enables historical price analysis.Table Name:actualizacion Engine: InnoDB Character Set: utf8mb4 Primary Key:id_actualizacion
Product: Vestido de Gala Rojo (ID: 3) First Update:1,100.00→1,200.00 (+9.09%) Second Update:1,200.00→1,350.00 (+12.5%) Total Change: $250.00 increase over 11 days Both authorized by: Karina Sánchez (Manager)
SELECT e.nombre as empleado, e.puesto, COUNT(*) as total_actualizaciones, AVG(a.precio_nuevo - a.precio_anterior) as cambio_promedio, MIN(a.fecha) as primera_actualizacion, MAX(a.fecha) as ultima_actualizacionFROM actualizacion aINNER JOIN empleado e ON a.id_empleado = e.id_empleadoGROUP BY e.id_empleado, e.nombre, e.puestoORDER BY total_actualizaciones DESC;
SELECT p.nombre as producto, COUNT(*) as num_cambios, MIN(a.precio_anterior) as precio_inicial, MAX(a.precio_nuevo) as precio_actual, (MAX(a.precio_nuevo) - MIN(a.precio_anterior)) as cambio_total, ROUND(((MAX(a.precio_nuevo) - MIN(a.precio_anterior)) / MIN(a.precio_anterior)) * 100, 2) as incremento_porcentualFROM actualizacion aINNER JOIN prenda p ON a.id_prenda = p.id_prendaGROUP BY p.id_prenda, p.nombreHAVING num_cambios > 1ORDER BY num_cambios DESC;
SELECT CASE WHEN precio_nuevo > precio_anterior THEN 'Aumento' WHEN precio_nuevo < precio_anterior THEN 'Reducción' ELSE 'Sin cambio' END as tipo_cambio, COUNT(*) as cantidad, AVG(ABS(precio_nuevo - precio_anterior)) as cambio_promedio, AVG(ABS((precio_nuevo - precio_anterior) / precio_anterior) * 100) as porcentaje_promedioFROM actualizacionGROUP BY tipo_cambio;
SELECT DATE_FORMAT(a.fecha, '%Y-%m') as mes, COUNT(*) as total_cambios, COUNT(DISTINCT a.id_prenda) as productos_afectados, AVG(a.precio_nuevo - a.precio_anterior) as cambio_promedio, SUM(CASE WHEN a.precio_nuevo > a.precio_anterior THEN 1 ELSE 0 END) as aumentos, SUM(CASE WHEN a.precio_nuevo < a.precio_anterior THEN 1 ELSE 0 END) as reduccionesFROM actualizacion aGROUP BY DATE_FORMAT(a.fecha, '%Y-%m')ORDER BY mes DESC;
SELECT p.nombre as producto, c.nombre as categoria, COUNT(a.id_actualizacion) as num_cambios, STDDEV(a.precio_nuevo - a.precio_anterior) as volatilidad, MIN(a.fecha) as primer_cambio, MAX(a.fecha) as ultimo_cambio, DATEDIFF(MAX(a.fecha), MIN(a.fecha)) as dias_historialFROM actualizacion aINNER JOIN prenda p ON a.id_prenda = p.id_prendaINNER JOIN categoria c ON p.id_categoria = c.id_categoriaGROUP BY p.id_prenda, p.nombre, c.nombreORDER BY volatilidad DESC;
Immutable Audit Trail: Price update records should never be modified or deleted. They form a legal audit trail for pricing history.
Synchronization Required: When creating an actualizacion record, the application must also update the corresponding prenda.precio field to the precio_nuevo value.
Manager Authorization: Price updates are typically restricted to managers (puesto = 'gerente'). In the sample data, all updates were performed by managers (employees 1 and 4).
Price Validation: Before inserting a record, validate that precio_anterior matches the current prenda.precio to prevent data inconsistencies.
SELECT p.nombre as producto, a.fecha, a.precio_nuevo as precio, ROW_NUMBER() OVER (PARTITION BY p.id_prenda ORDER BY a.fecha) as versionFROM actualizacion aINNER JOIN prenda p ON a.id_prenda = p.id_prendaWHERE p.id_prenda = 3ORDER BY a.fecha;
SELECT p.id_prenda, p.nombre, p.precio, c.nombre as categoriaFROM prenda pINNER JOIN categoria c ON p.id_categoria = c.id_categoriaLEFT JOIN actualizacion a ON p.id_prenda = a.id_prendaWHERE a.id_actualizacion IS NULLORDER BY p.precio DESC;
SELECT c.nombre as categoria, COUNT(DISTINCT p.id_prenda) as total_productos, COUNT(a.id_actualizacion) as total_actualizaciones, AVG(p.precio) as precio_promedio_actual, ROUND(COUNT(a.id_actualizacion) / COUNT(DISTINCT p.id_prenda), 2) as actualizaciones_por_productoFROM categoria cINNER JOIN prenda p ON c.id_categoria = p.id_categoriaLEFT JOIN actualizacion a ON p.id_prenda = a.id_prendaGROUP BY c.id_categoria, c.nombreORDER BY actualizaciones_por_producto DESC;
SELECT a.id_actualizacion, a.fecha as fecha_cambio, p.nombre as producto, c.nombre as categoria, a.precio_anterior, a.precio_nuevo, (a.precio_nuevo - a.precio_anterior) as diferencia, e.nombre as autorizado_por, e.puesto as cargo, CONCAT('$', FORMAT(a.precio_anterior, 2), ' → $', FORMAT(a.precio_nuevo, 2)) as resumenFROM actualizacion aINNER JOIN prenda p ON a.id_prenda = p.id_prendaINNER JOIN categoria c ON p.id_categoria = c.id_categoriaINNER JOIN empleado e ON a.id_empleado = e.id_empleadoWHERE a.fecha BETWEEN '2026-01-01' AND '2026-12-31'ORDER BY a.fecha DESC, a.id_actualizacion;