Calculation Views en SAP HANA

Modelos analíticos con tabla de hechos, dimensiones, medidas y variables dinámicas

📊 Arquitectura del Modelo Analítico

Componentes principales:

1. Tabla de Hechos (Fact Table)

Datos operacionales granulares. Ejemplo: cada venta realizada con cantidad, precio, fecha, cliente.

Campos típicos: ID de venta, ID cliente, ID producto, fecha, cantidad, precio unitario, descuento.

2. Tablas de Dimensiones (Dimensions)

Contexto descriptivo de la venta. Se unen con la tabla de hechos mediante claves foráneas.

Ejemplos: Dimensión Cliente (nombre, ciudad, país), Dimensión Producto (nombre, categoría, precio lista), Dimensión Tiempo (año, mes, trimestre).

3. Medidas Calculadas (Measures)

Agregaciones y ratios que responden preguntas de negocio.

Ejemplos: Total vendido (SUM), promedio de descuento (AVG), margen % (SUM(ganancia)/SUM(ingresos)).

4. Variables & Parámetros (Input Parameters)

Filtros dinámicos que el usuario selecciona en reportes/dashboards.

Ejemplos: Rango de fechas, país seleccionado, categoría de producto, vendedor.

Flujo de datos en la Calculation View:

Tabla de Hechos (Sales) ↓ [Join] Dimensión Cliente [Join] Dimensión Producto [Join] Dimensión Tiempo ↓ Medidas Calculadas (SUM, AVG, Ratios) ↓ Atributos Agrupados (por Cliente, Producto, Mes) ↓ Variables de Filtrado (p/ej: País = 'ES', Año = 2026) ↓ Resultado: Dataset optimizado para Analytics

📋 Tabla de Hechos: Sales (Ventas)

Definición en .hdbtable:

namespace logali.sales; @AbapCatalog.sqlViewName: 'SALES' @AccessControl.authorizationCheck: #CHECK @EndUserText.label: 'Ventas Realizadas' define table Sales { key ID: String; // ID única de venta CUSTOMER_ID: String; // FK a Dimensión Cliente PRODUCT_ID: String; // FK a Dimensión Producto SALE_DATE: Date; // Fecha de venta QUANTITY: Integer; // Cantidad vendida UNIT_PRICE: Decimal(10,2);// Precio unitario DISCOUNT_PCT: Decimal(5,2);// % descuento aplicado TOTAL_BEFORE_DISC: Decimal(15,2); // Subtotal TOTAL_AFTER_DISC: Decimal(15,2); // Total con descuento };

Datos de ejemplo:

ID CUSTOMER_ID PRODUCT_ID SALE_DATE QUANTITY UNIT_PRICE DISCOUNT_PCT TOTAL_AFTER_DISC
SAL-001 CUST-123 PROD-456 2026-05-01 5 100.00 10% 450.00
SAL-002 CUST-789 PROD-123 2026-05-02 2 250.00 5% 475.00
SAL-003 CUST-123 PROD-789 2026-05-03 10 50.00 15% 425.00

🔗 Dimensiones Relacionadas

Dimensión Cliente:

define table Customer { key CUSTOMER_ID: String; NAME: String; CITY: String; COUNTRY: String; SEGMENT: String; // 'Premium', 'Standard', 'Basic' };

Dimensión Producto:

define table Product { key PRODUCT_ID: String; NAME: String; CATEGORY: String; // 'Electrónica', 'Software', 'Servicios' LIST_PRICE: Decimal(10,2); COST: Decimal(10,2); // Costo de venta MARGIN_PCT: Decimal(5,2); // Margen típico };

Dimensión Tiempo:

define table Time { key DATE_ID: Date; YEAR: Integer; MONTH: Integer; QUARTER: Integer; WEEK: Integer; DAY_NAME: String; };

Joins en la Calculation View:

Sales (Tabla de Hechos) ↓ [Inner Join] Sales.CUSTOMER_ID = Customer.CUSTOMER_ID ↓ [Inner Join] Sales.PRODUCT_ID = Product.PRODUCT_ID ↓ [Inner Join] Sales.SALE_DATE = Time.DATE_ID ↓ Resultado: Un registro por venta con todos los atributos
💡 Nota sobre Joins: Los joins se hacen en memoria en HANA. Aunque haya millones de ventas, la velocidad de join es extremadamente rápida porque todo está en RAM. Sin HANA, tendrías que hacer estas búsquedas en disco (lentísimo).

📈 Medidas Calculadas

Tipos de medidas en la Calculation View:

Suma (SUM)

Ingresos Totales: SUM(Sales.TOTAL_AFTER_DISC)

Suma de todos los totales de venta.

Promedio (AVG)

Ticket Promedio: AVG(Sales.TOTAL_AFTER_DISC)

Promedio del valor de cada transacción.

Ratios (Divisiones)

Margen %: SUM(Product.COST) / SUM(Sales.TOTAL_AFTER_DISC) * 100

Porcentaje de utilidad respecto a ingresos.

Conteos (COUNT)

Total de Transacciones: COUNT(Sales.ID)

Número de ventas realizadas.

Máximo/Mínimo

Venta Mayor: MAX(Sales.TOTAL_AFTER_DISC)

Descuento Mínimo: MIN(Sales.DISCOUNT_PCT)

Ejemplo: Medidas en Cálculo View XML:

<measure name="TOTAL_SALES"> <measureColumns> <measureColumn columnName="TOTAL_AFTER_DISC"/> </measureColumns> <aggregationType>SUM</aggregationType> </measure> <measure name="AVG_TRANSACTION"> <measureColumns> <measureColumn columnName="TOTAL_AFTER_DISC"/> </measureColumns> <aggregationType>AVG</aggregationType> </measure> <measure name="MARGIN_RATIO"> <measureColumns> <measureColumn columnName="COST"/> <measureColumn columnName="TOTAL_AFTER_DISC"/> </measureColumns> <aggregationType>SUM</aggregationType> </measure>

🏷️ Atributos de Agrupación

Los atributos definen las dimensiones por las cuales se agrupan las medidas. Ejemplo:

Resultado agrupado por Cliente:

CUSTOMER_ID CUSTOMER_NAME CUSTOMER_COUNTRY TOTAL_SALES AVG_TRANSACTION TX_COUNT
CUST-123 Tech Corp ES 875.00 437.50 2
CUST-789 Solutions Ltd UK 475.00 475.00 1

Resultado agrupado por Producto y Mes:

PRODUCT_NAME CATEGORY YEAR-MONTH TOTAL_SALES QUANTITY_SOLD AVG_DISCOUNT
CloudSuite Software 2026-05 450.00 5 10%
Enterprise Suite Software 2026-05 475.00 2 5%
Support Services Servicios 2026-05 425.00 10 15%

Atributos disponibles para agrupar:

⚙️ Variables y Parámetros de Entrada

Las variables permiten que usuarios/dashboards filtren dinámicamente sin modificar la Calculation View.

Tipos de variables:

Variable Simple (Rango de fechas)
<variable name="START_DATE" datatype="DATE"> <defaultValue>2026-01-01</defaultValue> </variable> <variable name="END_DATE" datatype="DATE"> <defaultValue>2026-12-31</defaultValue> </variable> -- Uso en WHERE: WHERE Sales.SALE_DATE BETWEEN :START_DATE AND :END_DATE
Variable de Selección Única (País)
<variable name="COUNTRY" datatype="NVARCHAR" length="2"> <defaultValue>ES</defaultValue> </variable> -- Uso en WHERE: WHERE Customer.COUNTRY = :COUNTRY -- El usuario selecciona 'ES', 'UK', 'DE', etc.
Variable de Selección Múltiple (Categorías)
<variable name="CATEGORIES" datatype="NVARCHAR" length="50"> <defaultValue>'Software','Servicios'</defaultValue> <multiSelect>true</multiSelect> </variable> -- Uso en WHERE: WHERE Product.CATEGORY IN (:CATEGORIES) -- Usuario selecciona una o varias categorías
Variable de Segmento (Filtro de negocio)
<variable name="CUSTOMER_SEGMENT" datatype="NVARCHAR"> <defaultValue>Premium</defaultValue> <allowedValues> <value>Premium</value> <value>Standard</value> <value>Basic</value> </allowedValues> </variable> WHERE Customer.SEGMENT = :CUSTOMER_SEGMENT

Flujo de filtrado dinámico:

Usuario en SAP Analytics Cloud ↓ [Selecciona] País = 'ES', Fechas: 01/05 - 31/05 ↓ Dashboard envía parámetros a Calculation View ↓ WHERE COUNTRY='ES' AND SALE_DATE BETWEEN 2026-05-01 AND 2026-05-31 ↓ Resultado: Solo ventas de España en Mayo 2026 ↓ [Actualiza] Medidas en Dashboard (dinámicas)
💡 Ventaja de variables: Sin tocar el código, el usuario puede cambiar filtros en la UI. Los parámetros se reemplazan en la query automáticamente, haciendo que el resultado sea dinámico y rápido.

🎯 Caso Práctico: Dashboard de Ventas Regional

Requisito de negocio:

El VP de Ventas necesita ver ingresos, margen y ticket promedio por país y mes, con la opción de filtrar por rango de fechas y categoría de producto.

Estructura de la Calculation View:

┌─ Sales (Tabla de Hechos) │ ├─ ID, QUANTITY, UNIT_PRICE, DISCOUNT_PCT, TOTAL_AFTER_DISC │ ├─ [Join] Customer Dimension │ ├─ CUSTOMER_ID, COUNTRY, SEGMENT │ ├─ [Join] Product Dimension │ ├─ PRODUCT_ID, CATEGORY, COST │ └─ [Join] Time Dimension ├─ DATE_ID, YEAR, MONTH, QUARTER MEDIDAS: ├─ Total_Revenue = SUM(TOTAL_AFTER_DISC) ├─ Total_Cost = SUM(COST) ├─ Margin = (SUM(TOTAL_AFTER_DISC) - SUM(COST)) / SUM(TOTAL_AFTER_DISC) ├─ Avg_Ticket = AVG(TOTAL_AFTER_DISC) └─ Transaction_Count = COUNT(Sales.ID) ATRIBUTOS: ├─ COUNTRY ├─ MONTH ├─ CATEGORY └─ SEGMENT VARIABLES: ├─ START_DATE (default: 2026-01-01) ├─ END_DATE (default: 2026-12-31) └─ SELECTED_CATEGORY (default: todas)

Query SQL generada en HANA:

SELECT Customer.COUNTRY, Time.MONTH, Product.CATEGORY, SUM(Sales.TOTAL_AFTER_DISC) as Total_Revenue, SUM(Product.COST) as Total_Cost, SUM(Product.COST) / SUM(Sales.TOTAL_AFTER_DISC) as Margin_Ratio, AVG(Sales.TOTAL_AFTER_DISC) as Avg_Ticket, COUNT(Sales.ID) as Transaction_Count FROM Sales INNER JOIN Customer ON Sales.CUSTOMER_ID = Customer.CUSTOMER_ID INNER JOIN Product ON Sales.PRODUCT_ID = Product.PRODUCT_ID INNER JOIN Time ON Sales.SALE_DATE = Time.DATE_ID WHERE Sales.SALE_DATE BETWEEN :START_DATE AND :END_DATE AND Product.CATEGORY IN (:SELECTED_CATEGORY) GROUP BY Customer.COUNTRY, Time.MONTH, Product.CATEGORY ORDER BY Customer.COUNTRY, Time.MONTH

Resultado en Dashboard SAP Analytics Cloud:

COUNTRY MONTH CATEGORY Total_Revenue Margin_Ratio Avg_Ticket Tx_Count
ES May-2026 Software 925,000 35% 450 2,055
ES May-2026 Servicios 425,000 42% 380 1,118
UK May-2026 Software 1,250,000 33% 520 2,404
UK May-2026 Servicios 675,000 38% 445 1,516

Interacción del usuario:

✅ Checklist de Implementación

🚀 Resultado final: Un modelo de datos listo para que usuarios no-técnicos creen dashboards interactivos, cambien filtros dinámicamente, y tomen decisiones en tiempo real basadas en datos de millones de registros procesados en RAM.