Fecha más reciente relativa a otra columna en Power Query
TL;DR: Para obtener, por cada grupo, la fecha más reciente anterior a una fecha de referencia, agrupa con Table.Group, filtra dentro de cada subtabla las filas cuya dateAdded <= Max Date Reported y quédate con el máximo de esas. Se resuelve entero en Power Query con Table.Group + Table.SelectRows + List.Max, sin medidas DAX ni columnas auxiliares manuales.
Es uno de esos problemas que parecen triviales hasta que los tienes delante: una tabla donde cada combinación se repite muchas veces, y necesitas quedarte con una sola fila por grupo según una regla temporal. En el foro oficial de Microsoft Fabric, la consulta sobre cómo encontrar la fecha más reciente relativa a otra columna acumula más de 157.000 vistas, señal de que mucha gente se ha quedado atascada exactamente aquí.
El planteamiento típico es este: tienes una columna dateAdded que se repite y una Max Date Reported que actúa como fecha de corte. Para cada grupo no quieres la fecha más nueva en términos absolutos, sino la más reciente que siga siendo anterior o igual a la fecha de referencia. Es una diferencia sutil que cambia por completo el resultado.
¿Por qué no basta con ordenar y quitar duplicados?
La tentación es ordenar por dateAdded descendente y aplicar Quitar duplicados. No funciona por dos motivos.
Primero, Quitar duplicados en Power Query conserva la primera fila que encuentra, y el orden no siempre se respeta tras pasos posteriores: el motor puede reordenar internamente al hacer folding. Confiar en el orden visual es frágil.
Segundo, y más importante, no estás buscando el máximo absoluto. Estás buscando el máximo dentro de un subconjunto filtrado (las fechas que no superan el corte). Eso obliga a razonar grupo por grupo, no fila por fila.
¿Cuándo aparece este patrón?
- Pólizas y siniestros: la última actualización registrada antes de la fecha de reporte.
- Precios: el precio vigente más reciente anterior a la fecha de una venta.
- Inventarios: el último movimiento de stock previo a un cierre contable.
- Scoring: el score más reciente calculado antes de una fecha de evaluación.
En todos, la lógica es la misma: para cada clave, la fila más reciente que no se pase de una fecha tope.
¿Cómo se hace en Power Query paso a paso?
La estrategia es agrupar por la clave del grupo y, dentro de cada subtabla, aplicar el filtro temporal antes de tomar el máximo.
Paso 1: asegurar los tipos de fecha
Antes de comparar, ambas columnas deben ser de tipo date o datetime. Comparar texto con apariencia de fecha produce resultados silenciosamente incorrectos.
let
Origen = Excel.CurrentWorkbook(){[Name="Datos"]}[Content],
Tipos = Table.TransformColumnTypes(
Origen,
{
{"Max Date Reported", type date},
{"dateAdded", type datetime}
}
)
in
Tipos
Paso 2: agrupar y resolver dentro de cada grupo
Aquí está el núcleo de la solución. Agrupamos por la clave (contactId y Number en este ejemplo) y, en la operación de agregación, trabajamos sobre la subtabla completa de cada grupo:
let
Origen = Tipos,
Agrupado = Table.Group(
Origen,
{"contactId", "Number"},
{
{"FilaElegida", each
let
// La fecha de corte es la misma dentro del grupo
Corte = List.Max([Max Date Reported]),
// Solo las filas cuya dateAdded no supera el corte
Validas = Table.SelectRows(_, (r) => r[dateAdded] <= Corte),
// La más reciente de entre las válidas
FechaMax = List.Max(Validas[dateAdded]),
Resultado = Table.SelectRows(Validas, (r) => r[dateAdded] = FechaMax)
in
Resultado,
type table}
}
)
in
Agrupado
La clave está en el _ dentro de each: representa la subtabla del grupo actual, no la tabla completa. Sobre ella filtramos con Table.SelectRows y tomamos el máximo con List.Max.
Paso 3: expandir la fila elegida
Table.Group deja una columna de tablas anidadas. La expandimos para recuperar las columnas originales:
let
Origen = Agrupado,
Expandido = Table.ExpandTableColumn(
Origen,
"FilaElegida",
{"policyId", "score", "dateAdded"},
{"policyId", "score", "dateAdded"}
)
in
Expandido
El resultado: una fila por grupo, con la fecha más reciente que respeta el corte y todas sus columnas asociadas (como el score que le corresponde a esa fecha exacta).
Variante: ¿y si quiero estrictamente anterior, no «anterior o igual»?
Cambia el operador de comparación de <= a < en el filtro de filas válidas:
Validas = Table.SelectRows(_, (r) => r[dateAdded] < Corte),
Pequeño detalle, gran diferencia. Decide según tu negocio si la fecha del mismo día cuenta o no.
Errores comunes
| Síntoma | Causa | Solución |
|---|---|---|
| Devuelve la fecha futura, no la pasada | Falta el filtro de corte; se toma el máximo absoluto | Aplicar Table.SelectRows con <= Corte antes de List.Max |
Expression.Error al comparar |
Una columna es texto, no fecha | Forzar type date/type datetime en el Paso 1 |
| Grupos con resultado vacío | Ninguna fila cumple el corte en ese grupo | Decidir el comportamiento: dejar null o relajar a <= |
| Rendimiento lento en millones de filas | List.Max recalcula el corte por fila |
Calcular Corte una vez dentro del let, como en el ejemplo |
Conclusión
Este patrón —agrupar, filtrar dentro del grupo y tomar el extremo— es uno de los más reutilizables del Lenguaje M. Una vez lo interiorizas, dejas de exportar a Excel para resolver «a mano» lo que Power Query hace en un solo paso, de forma reproducible y a prueba de refrescos.
Si quieres dominar Table.Group, las funciones de lista y los patrones de agregación personalizada que hacen posible esto, el siguiente curso los cubre con casos reales:

Power Query: Lenguaje M aplicado a casos prácticos Office365 Excel
Fuente: hilo del foro oficial de Microsoft Fabric con más de 157.000 vistas, solución verificada por la comunidad.

Deja una respuesta