Lección 11 de 16 · Nivel 3: Avanzado

DAX avanzado y rendimiento: variables, rankings, Top N y clientes nuevos

  • ⏱ 9 min de lectura
  • ❓ 3 preguntas de repaso
  • ✍️ Ejercicio con solución
En esta lección
  1. Variables: VAR y RETURN
  2. Rankings con RANKX
  3. Top N: ventas de los 5 mejores productos
  4. Segmentar clientes con SWITCH(TRUE())
  5. Clientes nuevos
  6. Relaciones inactivas: USERELATIONSHIP
  7. Rendimiento: cuando el informe va lento
  8. Resumen
Lo que lograrás en esta lección
  • Escribir medidas más legibles y rápidas con variables (VAR y RETURN).
  • Crear rankings, Top N y segmentos de clientes.
  • Calcular clientes nuevos y usar relaciones inactivas con USERELATIONSHIP.
  • Diagnosticar y mejorar el rendimiento de un informe lento.

Con CALCULATE, el contexto de filtro y la inteligencia de tiempo ya resuelves la mayoría de los informes. Esta lección te da las técnicas que usan los profesionales para los casos difíciles, y te enseña a encontrar por qué un informe va lento.

Variables: VAR y RETURN

Las variables guardan un resultado intermedio con nombre. Hacen las medidas más legibles, evitan calcular lo mismo dos veces y facilitan encontrar errores:

Var % Año Anterior =
VAR VentasActual   = [Ventas Totales]
VAR VentasAnterior = [Ventas Año Anterior]
RETURN
    IF (
        NOT ISBLANK ( VentasAnterior ),
        DIVIDE ( VentasActual - VentasAnterior, VentasAnterior )
    )
  • Una variable se calcula en el contexto donde se define y su valor no cambia después, aunque la uses dentro de un CALCULATE.
  • Para depurar, cambia temporalmente el RETURN por una de las variables y verás su valor en el objeto visual.

Rankings con RANKX

Ranking Producto =
IF (
    ISINSCOPE ( Productos[Producto] ),
    RANKX ( ALL ( Productos[Producto] ), [Ventas Totales] )
)
  • ALL(Productos[Producto]): la lista completa de productos contra la que se compara (si usaras solo los visibles, cada fila se compararía consigo misma y todas tendrían el puesto 1).
  • ISINSCOPE: evita mostrar un ranking sin sentido en la fila de total.
  • Con la tabla de ejemplo de la lección 6: Arroz (162) es 1.º, Aceite (117) 2.º y Azúcar (45,60) 3.º.
  • Si el usuario filtra una ciudad, el ranking se recalcula con las ventas de esa ciudad, porque ALL solo quita el filtro de la columna Producto.

Top N: ventas de los 5 mejores productos

Ventas Top 5 Productos =
CALCULATE (
    [Ventas Totales],
    TOPN ( 5, ALL ( Productos[Producto] ), [Ventas Totales] )
)

% Ventas Top 5 =
DIVIDE ( [Ventas Top 5 Productos], [Ventas Totales] )

TOPN devuelve una tabla con los 5 productos de más ventas en el contexto actual, que CALCULATE usa como filtro. "% Ventas Top 5" mide la concentración: si 5 productos hacen el 70% de las ventas, el negocio depende mucho de ellos. Para mostrar solo los 10 primeros en un gráfico, no necesitas DAX: usa el filtro N superior del objeto visual (lección 3).

1. Tu medida de ranking muestra "1" en todas las filas de la tabla. ¿Cuál es la causa más probable?

  • Todos los productos venden lo mismo.
  • RANKX se aplica sobre la tabla filtrada por la fila (cada producto se compara solo consigo mismo); hay que usar ALL(Productos[Producto]).
  • Falta la tabla de fechas.

El primer argumento de RANKX debe ser la lista completa de elementos que compiten, sin el filtro de la fila.

Segmentar clientes con SWITCH(TRUE())

Clasifica a los clientes por sus compras históricas con una columna calculada en la tabla Clientes (así podrás usar el segmento en segmentaciones y ejes):

Segmento =
VAR VentasCliente = [Ventas Totales]
RETURN
    SWITCH (
        TRUE (),
        VentasCliente >= 10000, "A · Grande",
        VentasCliente >= 3000,  "B · Mediano",
        VentasCliente > 0,      "C · Pequeño",
        "Sin compras"
    )

SWITCH(TRUE(), …) evalúa las condiciones en orden y devuelve el resultado de la primera verdadera: es el SI.CONJUNTO de DAX. Al usar la medida [Ventas Totales] en una columna calculada, la transición de contexto (lección 7) hace que calcule las ventas de cada cliente. Recuerda que una columna calculada se recalcula al actualizar los datos, no al filtrar: el segmento es fijo para el periodo cargado.

Clientes nuevos

Un cliente es nuevo en un periodo si su primera compra de toda la historia cae dentro de ese periodo:

Clientes Nuevos =
VAR InicioPeriodo = MIN ( Calendario[Date] )
VAR ClientesConPrimeraCompra =
    ADDCOLUMNS (
        VALUES ( Ventas[IdCliente] ),
        "@PrimeraCompra", CALCULATE ( MIN ( Ventas[Fecha] ), REMOVEFILTERS ( Calendario ) )
    )
RETURN
    COUNTROWS ( FILTER ( ClientesConPrimeraCompra, [@PrimeraCompra] >= InicioPeriodo ) )
  • VALUES(Ventas[IdCliente]): los clientes que compraron en el periodo actual.
  • Para cada uno, CALCULATE con REMOVEFILTERS(Calendario) busca su primera compra sin filtro de fechas.
  • Se cuentan los que la hicieron desde el inicio del periodo.

Con esta medida, "Clientes Recurrentes" es simplemente [Clientes] - [Clientes Nuevos].

Relaciones inactivas: USERELATIONSHIP

Si la tabla Ventas tiene Fecha de pedido y Fecha de entrega, solo una relación con Calendario puede estar activa (lección 5). La otra queda inactiva (línea discontinua) y se activa dentro de una medida:

Ventas por Fecha de Entrega =
CALCULATE (
    [Ventas Totales],
    USERELATIONSHIP ( Ventas[FechaEntrega], Calendario[Date] )
)

2. ¿Por qué Clientes Nuevos usa REMOVEFILTERS(Calendario) al buscar la primera compra?

  • Para que la medida sea más rápida.
  • Para encontrar la primera compra de toda la historia del cliente, no solo la primera dentro del periodo filtrado.
  • Porque la tabla Calendario tiene errores.

Sin quitar el filtro de fechas, la "primera compra" sería siempre dentro del periodo y todos los clientes parecerían nuevos.

Rendimiento: cuando el informe va lento

Paso 1: mide

Abre Ver → Analizador de rendimiento, pulsa Iniciar grabación y Actualizar objetos visuales. Verás cuántos milisegundos tarda cada objeto, separado en consulta DAX, presentación y otros. Ataca primero los más lentos. Para análisis más profundos existe la herramienta externa gratuita DAX Studio.

Paso 2: aplica las mejoras con más impacto

ProblemaMejora
Modelo grandeElimina en Power Query las columnas y filas que no usas; cada columna ocupa memoria
Columnas con muchos valores distintos (identificadores de transacción, fecha y hora con segundos)Quítalas si no las necesitas; separa fecha y hora; redondea decimales innecesarios
Una tabla gigante con todoModelo en estrella (lección 5)
Relaciones bidireccionalesÚsalas solo cuando sea imprescindible
FILTER sobre tablas de hechos enterasFiltra columnas o dimensiones; usa filtros simples en CALCULATE
Medidas que calculan lo mismo varias vecesVariables
Demasiados objetos visuales por páginaMenos objetos, más tooltips y obtención de detalles (lección 9)
Columnas calculadas complejasMuévelas a Power Query o a la fuente cuando sea posible
Importar o DirectQuery

En modo Importar (el habitual), los datos se copian y comprimen en el modelo: es muy rápido, pero se actualiza según la programación. En DirectQuery, cada clic consulta la base de datos de origen en tiempo real: datos siempre al día, pero más lento y con limitaciones de DAX. Elige DirectQuery solo cuando necesites datos casi en tiempo real o el volumen sea enorme.

3. El Analizador de rendimiento muestra que una matriz tarda 9 segundos en la consulta DAX. ¿Qué revisas primero?

  • El color del tema.
  • Las medidas que usa: FILTER sobre tablas grandes, cálculos repetidos y relaciones bidireccionales.
  • El tamaño de la fuente de los títulos.

Si el tiempo está en la consulta DAX, el problema está en las medidas o en el modelo, no en el diseño visual.

Ejercicio práctico: análisis de clientes avanzado

  1. Reescribe "Var % Año Anterior" con variables.
  2. Crea "Ranking Cliente" y una tabla con los clientes ordenados por ranking.
  3. Crea la columna Segmento (A, B, C) y un gráfico de ventas por segmento.
  4. Crea "Clientes Nuevos" y "Clientes Recurrentes" y muéstralos por mes.
  5. Usa el Analizador de rendimiento en tu informe e identifica el objeto visual más lento.
Ver una medida extra: clientes perdidos
Clientes Perdidos =
-- Compraron en los 90 días anteriores al periodo, pero no en el periodo
VAR InicioPeriodo = MIN ( Calendario[Date] )
VAR ClientesAntes =
    CALCULATETABLE (
        VALUES ( Ventas[IdCliente] ),
        DATESBETWEEN ( Calendario[Date], InicioPeriodo - 90, InicioPeriodo - 1 )
    )
VAR ClientesAhora = VALUES ( Ventas[IdCliente] )
RETURN
    COUNTROWS ( EXCEPT ( ClientesAntes, ClientesAhora ) )

EXCEPT devuelve las filas de la primera tabla que no están en la segunda. Esta medida es la base de la página "Clientes que dejaron de comprar" que planificaste en la lección 4.

Resumen

  • Las variables hacen las medidas más claras, más rápidas y fáciles de depurar.
  • RANKX con ALL crea rankings; TOPN calcula el peso de los N mejores.
  • SWITCH(TRUE()) clasifica en segmentos; REMOVEFILTERS permite calcular la primera compra y los clientes nuevos.
  • USERELATIONSHIP activa relaciones inactivas dentro de una medida.
  • Mide con el Analizador de rendimiento y simplifica el modelo antes de culpar a Power BI.

En la próxima lección reunirás todo en un proyecto final: el panel de ventas completo de Distribuidora Andina, de los datos sin limpiar a la publicación.

🎓 Guarda tu avance y obtén tu certificado gratis

Crea tu cuenta en 30 segundos, marca tus lecciones y descarga el certificado al terminar.

Inscribirme gratis