Hoja de trucos de Power BI
Última actualización
Medidas, columnas y tablas
Una medida se calcula para cada celda de un objeto visual; una columna calculada se calcula una vez por fila y se guarda.
| Qué hace | DAX |
|---|---|
| Crear una medida | Total Sales = SUM ( Sales[Amount] ) |
| Crear una columna calculada (un valor por fila) | Line Total = Sales[Quantity] * Sales[Unit Price] |
| Crear una tabla calculada | Top Customers = TOPN ( 10, Customer, [Total Sales] ) |
| Hacer referencia a una columna: el nombre de la tabla y luego la columna entre corchetes | Sales[Amount] |
| Poner entre comillas un nombre de tabla que tiene un espacio o es una palabra reservada | 'Date'[Date] |
| Hacer referencia a una medida: solo corchetes | [Total Sales] |
| Usar una medida dentro de otra medida | Average Price = DIVIDE ( [Total Sales], [Total Units] ) |
Funciones de agregación
Cada una resume una columna en el contexto de filtro actual.
| Qué hace | DAX |
|---|---|
| Sumar una columna | SUM ( Sales[Amount] ) |
| Promedio de una columna | AVERAGE ( Sales[Amount] ) |
| Valor más pequeño | MIN ( Sales[Order Date] ) |
| Valor más grande | MAX ( Sales[Order Date] ) |
| Contar las filas de una tabla | COUNTROWS ( Sales ) |
| Contar los valores de una columna que no están en blanco | COUNT ( Sales[Amount] ) |
| Contar valores distintos | DISTINCTCOUNT ( Sales[Customer Key] ) |
| Dividir sin riesgo: un valor en blanco en vez de un error cuando el divisor es 0 | DIVIDE ( [Total Sales], [Total Units] ) |
| Dividir con un valor que mostrar cuando el divisor es 0 | DIVIDE ( [Profit], [Total Sales], 0 ) |
Iteradores (las funciones X)
Recorren una tabla fila por fila, evalúan una expresión en cada fila y luego agregan los resultados.
| Qué hace | DAX |
|---|---|
| Multiplicar por fila y luego sumar | SUMX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| Promedio de un resultado por fila | AVERAGEX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| Mayor resultado por fila | MAXX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| Promedio de una medida por cliente | AVERAGEX ( VALUES ( Customer[Customer Key] ), [Total Sales] ) |
| Usar una columna de una tabla relacionada en la expresión | SUMX ( Sales, Sales[Quantity] * RELATED ( Product[Unit Cost] ) ) |
| Contar las filas que cumplen una condición | COUNTROWS ( FILTER ( Sales, Sales[Quantity] >= 3 ) ) |
| Clasificar cada producto según una medida | RANKX ( ALL ( Product[Product] ), [Total Sales] ) |
| Clasificar sin huecos tras los empates (1, 1, 2) | RANKX ( ALL ( Product[Product] ), [Total Sales], , DESC, DENSE ) |
| Unir valores en un solo texto | CONCATENATEX ( VALUES ( Product[Category] ), Product[Category], ", " ) |
CALCULATE y funciones de filtro
CALCULATE evalúa una expresión con los filtros cambiados. Un filtro sobre la misma columna sustituye al anterior; los filtros sobre columnas distintas se combinan con AND.
| Qué hace | DAX |
|---|---|
| Filtrar por un valor | CALCULATE ( [Total Sales], Product[Category] = "Bikes" ) |
| Filtrar por una lista de valores | CALCULATE ( [Total Sales], Product[Color] IN { "Red", "Blue" } ) |
| Dos filtros (AND) | CALCULATE ( [Total Sales], Product[Color] = "Red", Store[Country] = "Spain" ) |
| OR entre dos columnas | CALCULATE ( [Total Sales], FILTER ( ALL ( Product[Color], Product[Brand] ), Product[Color] = "Red" || Product[Brand] = "Contoso" ) ) |
| Filtrar por una medida | CALCULATE ( [Total Sales], FILTER ( VALUES ( Customer[Customer Key] ), [Total Sales] > 1000 ) ) |
| Mantener el filtro existente y cruzarlo con el nuevo | CALCULATE ( [Total Sales], KEEPFILTERS ( Product[Color] IN { "Red", "Blue" } ) ) |
| Quitar los filtros de una columna | CALCULATE ( [Total Sales], REMOVEFILTERS ( Product[Category] ) ) |
| Quitar todos los filtros de una tabla | CALCULATE ( [Total Sales], ALL ( Product ) ) |
| Quitar todos los filtros de una tabla salvo algunas columnas | CALCULATE ( [Total Sales], ALLEXCEPT ( Store, Store[Country] ) ) |
| Mantener la selección de las segmentaciones e ignorar las filas del propio objeto visual | CALCULATE ( [Total Sales], ALLSELECTED ( Product[Category] ) ) |
| Usar una relación inactiva | CALCULATE ( [Total Sales], USERELATIONSHIP ( Sales[Ship Date], 'Date'[Date] ) ) |
| Hacer que un filtro fluya en ambas direcciones para una medida | CALCULATE ( COUNTROWS ( Customer ), CROSSFILTER ( Sales[Customer Key], Customer[Customer Key], BOTH ) ) |
| Filtrar con una tabla que no tiene relación | CALCULATE ( [Total Sales], TREATAS ( VALUES ( Budget[Category] ), Product[Category] ) ) |
Inteligencia de tiempo
Necesitan una tabla de fechas: una fila por día, sin huecos y marcada como tabla de fechas.
| Qué hace | DAX |
|---|---|
| Acumulado del año | TOTALYTD ( [Total Sales], 'Date'[Date] ) |
| Acumulado del año, con un año fiscal que termina el 30 de junio | TOTALYTD ( [Total Sales], 'Date'[Date], "6/30" ) |
| Acumulado del año dentro de CALCULATE | CALCULATE ( [Total Sales], DATESYTD ( 'Date'[Date] ) ) |
| Acumulado del trimestre | TOTALQTD ( [Total Sales], 'Date'[Date] ) |
| Acumulado del mes | TOTALMTD ( [Total Sales], 'Date'[Date] ) |
| Mismo periodo del año anterior | CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) |
| Desplazar las fechas un intervalo (aquí, un mes atrás) | CALCULATE ( [Total Sales], DATEADD ( 'Date'[Date], -1, MONTH ) ) |
| El mes anterior completo | CALCULATE ( [Total Sales], PREVIOUSMONTH ( 'Date'[Date] ) ) |
| El periodo completo un año atrás | CALCULATE ( [Total Sales], PARALLELPERIOD ( 'Date'[Date], -1, YEAR ) ) |
| Los últimos 12 meses hasta la última fecha visible | CALCULATE ( [Total Sales], DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -12, MONTH ) ) |
| Un rango de fechas fijo | CALCULATE ( [Total Sales], DATESBETWEEN ( 'Date'[Date], DATE ( 2025, 1, 1 ), DATE ( 2025, 3, 31 ) ) ) |
Patrones de medidas comunes
Cópialos y cambia los nombres de tablas y columnas para que coincidan con tu modelo.
| Qué hace | DAX |
|---|---|
| Porcentaje sobre todas las categorías | Category % = DIVIDE ( [Total Sales], CALCULATE ( [Total Sales], REMOVEFILTERS ( Product[Category] ) ) ) |
| Porcentaje sobre lo que dejan las segmentaciones | Visible % = DIVIDE ( [Total Sales], CALCULATE ( [Total Sales], ALLSELECTED ( Product[Category] ) ) ) |
| Crecimiento interanual | YoY % = VAR LastYear = CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) RETURN DIVIDE ( [Total Sales] - LastYear, LastYear ) |
| Total acumulado desde el principio | Running Total = CALCULATE ( [Total Sales], FILTER ( ALL ( 'Date'[Date] ), 'Date'[Date] <= MAX ( 'Date'[Date] ) ) ) |
| Media móvil de 7 días (por día con ventas) | Sales 7 Day Avg = AVERAGEX ( DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -7, DAY ), [Total Sales] ) |
| Mostrar un valor solo para los 5 primeros | Top 5 Sales = IF ( RANKX ( ALLSELECTED ( Product[Product] ), [Total Sales] ) <= 5, [Total Sales] ) |
| Contar los clientes por encima de un umbral | Big Customers = COUNTROWS ( FILTER ( VALUES ( Customer[Customer Key] ), [Total Sales] > 1000 ) ) |
| Hacer que un total sume sus filas | Bonus Total = SUMX ( VALUES ( Product[Category] ), [Bonus] ) |
| Mostrar un valor solo en un nivel de una matriz | Category Rank = IF ( ISINSCOPE ( Product[Category] ), RANKX ( ALL ( Product[Category] ), [Total Sales] ) ) |
| Saldo de cierre: la última fecha que tiene un valor | Closing Units = CALCULATE ( SUM ( Inventory[Units] ), LASTNONBLANK ( 'Date'[Date], CALCULATE ( SUM ( Inventory[Units] ) ) ) ) |
Funciones lógicas y de información
Para condiciones y para saber qué contiene el contexto de filtro.
| Qué hace | DAX |
|---|---|
| Una condición | IF ( [Total Sales] > 1000, "High", "Low" ) |
| Varios valores de una expresión | SWITCH ( Store[Country], "Spain", "ES", "Portugal", "PT", "Other" ) |
| Rangos, comprobados de arriba abajo | SWITCH ( TRUE (), [Total Sales] >= 10000, "A", [Total Sales] >= 1000, "B", "C" ) |
| AND y OR | IF ( Sales[Quantity] > 2 && Sales[Amount] > 50, "Big", "Small" ) |
| ¿El valor está en blanco? | ISBLANK ( [Total Sales] ) |
| Primer valor que no está en blanco | COALESCE ( [Total Sales], 0 ) |
| ¿El filtro deja exactamente un valor? | HASONEVALUE ( Product[Category] ) |
| Ese único valor, o uno predeterminado | SELECTEDVALUE ( Product[Category], "All categories" ) |
| ¿Esta fila del objeto visual está agrupada por la columna? | ISINSCOPE ( Product[Category] ) |
| Devolver un valor en blanco | BLANK () |
Funciones de texto
El operador & une texto; FORMAT convierte un número o una fecha en texto.
| Qué hace | DAX |
|---|---|
| Unir texto | Customer[First Name] & " " & Customer[Last Name] |
| Dar formato a un número | FORMAT ( [Total Sales], "#,0.00" ) |
| Dar formato a una fecha | FORMAT ( 'Date'[Date], "mmm yyyy" ) |
| Primeros caracteres | LEFT ( Product[Code], 3 ) |
| Caracteres desde una posición | MID ( Product[Code], 4, 2 ) |
| Longitud | LEN ( Product[Name] ) |
| Mayúsculas | UPPER ( Store[City] ) |
| Quitar espacios sobrantes | TRIM ( Customer[Name] ) |
| Reemplazar texto | SUBSTITUTE ( Customer[Phone], " ", "" ) |
| Posición de un texto, sin distinguir mayúsculas (0 si no aparece) | SEARCH ( "pro", Product[Name], 1, 0 ) |
Funciones de fecha
Por debajo, las fechas son números, así que puedes restarlas para obtener días.
| Qué hace | DAX |
|---|---|
| La fecha de hoy | TODAY () |
| Construir una fecha | DATE ( 2025, 12, 31 ) |
| Año de una fecha | YEAR ( 'Date'[Date] ) |
| Número del mes | MONTH ( 'Date'[Date] ) |
| Día de la semana, con el lunes como 1 | WEEKDAY ( 'Date'[Date], 2 ) |
| Número de semana, con semanas que empiezan el lunes | WEEKNUM ( 'Date'[Date], 2 ) |
| Último día del mes | EOMONTH ( 'Date'[Date], 0 ) |
| El mismo día un mes antes | EDATE ( 'Date'[Date], -1 ) |
| Días entre dos fechas | DATEDIFF ( Sales[Order Date], Sales[Ship Date], DAY ) |
| Una tabla de fechas a partir de fechas fijas | CALENDAR ( DATE ( 2024, 1, 1 ), DATE ( 2025, 12, 31 ) ) |
| Una tabla de fechas a partir de las fechas del modelo | CALENDARAUTO () |
Relaciones y búsquedas
RELATED sigue una relación desde el lado de muchos hasta el lado de uno.
| Qué hace | DAX |
|---|---|
| Valor del lado de uno (en una columna de Sales) | RELATED ( Product[Category] ) |
| Las filas del lado de muchos de la fila actual (en una columna de Customer) | COUNTROWS ( RELATEDTABLE ( Sales ) ) |
| Buscar un valor sin relación | LOOKUPVALUE ( Product[Price], Product[SKU], Sales[SKU] ) |
| Ruta padre e hijo (para jerarquías y seguridad de nivel de fila) | PATH ( Employee[Employee ID], Employee[Manager ID] ) |
| El usuario que ha iniciado sesión, para la seguridad dinámica de nivel de fila | USERPRINCIPALNAME () |
Funciones de tabla
Devuelven tablas: úsalas en una tabla calculada, dentro de CALCULATE o en un iterador.
| Qué hace | DAX |
|---|---|
| Valores distintos en el filtro actual | VALUES ( Product[Category] ) |
| Filas que cumplen una condición | FILTER ( Product, Product[Price] > 100 ) |
| Las N primeras filas según una medida | TOPN ( 5, ALL ( Product[Product] ), [Total Sales] ) |
| Agrupar por columnas y añadir medidas | SUMMARIZECOLUMNS ( Product[Category], "Sales", [Total Sales] ) |
| Añadir una columna a una tabla | ADDCOLUMNS ( VALUES ( Product[Category] ), "Sales", [Total Sales] ) |
| Elegir columnas y cambiarles el nombre | SELECTCOLUMNS ( Customer, "Name", Customer[Name], "City", Customer[City] ) |
| Una lista de números | GENERATESERIES ( 1, 10, 1 ) |
| Todas las combinaciones de dos tablas | CROSSJOIN ( VALUES ( 'Date'[Year] ), VALUES ( Product[Category] ) ) |
| Apilar dos tablas con las mismas columnas | UNION ( 'Sales 2024', 'Sales 2025' ) |
Variables
VAR da nombre a un paso y lo calcula una sola vez; RETURN devuelve el resultado.
| Qué hace | DAX |
|---|---|
| Una variable | Margin % = VAR Revenue = [Total Sales] RETURN DIVIDE ( Revenue - [Total Cost], Revenue ) |
| Varias variables | Sales vs LY = VAR CY = [Total Sales] VAR PY = CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) RETURN CY - PY |
| Una tabla en una variable | Top 5 Total = VAR Top5 = TOPN ( 5, ALL ( Product[Product] ), [Total Sales] ) RETURN CALCULATE ( [Total Sales], Top5 ) |
Pasos de Power Query (M)
Power Query da forma a los datos antes de cargarlos. Estas son las fórmulas M que hay detrás de los botones más comunes.
| Qué hace | M |
|---|---|
| Conservar las filas que coinciden | Table.SelectRows(Source, each [Status] = "Paid") |
| Quitar columnas | Table.RemoveColumns(Source, {"Notes", "Temp"}) |
| Definir los tipos de columna | Table.TransformColumnTypes(Source, {{"Amount", type number}, {"Date", type date}}) |
| Cambiar el nombre de una columna | Table.RenameColumns(Source, {{"amt", "Amount"}}) |
| Agregar una columna | Table.AddColumn(Source, "Total", each [Quantity] * [Price], type number) |
| Combinar (join) dos consultas | Table.NestedJoin(Sales, {"ProductID"}, Products, {"ProductID"}, "Product", JoinKind.LeftOuter) |
| Anexar (apilar) consultas | Table.Combine({Sales2024, Sales2025}) |
| Anular la dinamización de columnas para pasarlas a filas | Table.UnpivotOtherColumns(Source, {"Product"}, "Month", "Amount") |
| Agrupar y agregar | Table.Group(Source, {"Category"}, {{"Sales", each List.Sum([Amount]), type number}}) |
| Reemplazar los errores por un valor | Table.ReplaceErrorValues(Source, {{"Amount", 0}}) |
Esta hoja de trucos de Power BI reúne en una sola página el DAX que más se escribe: agregaciones, los iteradores X, CALCULATE y las funciones que cambian filtros, inteligencia de tiempo, funciones de texto y de fecha, y patrones de medidas que puedes copiar, como el porcentaje del total, el crecimiento interanual y los totales acumulados.
Los ejemplos usan un modelo de ventas con las tablas Sales, Product, Customer y 'Date'; cambia los nombres para que coincidan con los tuyos. El DAX se ha analizado con el motor del curso de Power BI de Coddy, donde puedes escribirlo en un espacio de Power BI en tu navegador y comprobarlo.
Preguntas frecuentes sobre la hoja de trucos de Power BI
¿Esta hoja de trucos de Power BI es gratis?
Sí. Léela aquí o guárdala en marcadores; no hace falta registrarse.
¿Qué diferencia hay entre una medida y una columna calculada?
Una columna calculada se calcula una vez por fila al actualizar y se guarda, así que puedes segmentar por ella. Una medida se calcula para cada celda de un objeto visual, con los filtros de esa celda, y no guarda nada. Los totales y los cocientes van en medidas.
¿Qué hace CALCULATE?
Evalúa una expresión con los filtros cambiados: añade, sustituye o quita filtros y luego calcula el resultado. Casi todo el DAX que va más allá de los totales simples es CALCULATE con los argumentos de filtro adecuados.
¿Por qué usar DIVIDE en lugar del operador /?
DIVIDE devuelve un valor en blanco (o el valor que elijas) cuando el divisor es cero o está en blanco. El operador / devuelve infinito o un valor de error, que aparece en los objetos visuales.¿Necesito una tabla de fechas para la inteligencia de tiempo?
TOTALYTD y SAMEPERIODLASTYEAR necesitan una tabla con una fila por día, sin huecos y con años completos, relacionada con tus tablas de hechos y marcada como tabla de fechas.¿Este DAX funciona en Power Pivot de Excel y en Analysis Services?
El lenguaje DAX es el mismo, así que casi todo funciona también allí. Algunas funciones más nuevas llegan antes a Power BI.
¿Dónde puedo practicar DAX?
En el curso de Power BI de Coddy: cada lección te da un espacio de Power BI en el navegador y comprueba tu medida con los datos de la lección y con copias ocultas de ellos.