Hoy veremos diferentes alternativas con Power Query para recuperar los últimos valores registrados, de acuerdo a distintas condiciones.
A partir de nuestra tabla de datos, deseamos recuperar aquellos registros únicos que respondan a un criterio múltiple (País y Producto), pero que hayan sido los últimos en registrarse según un campo de orden, fecha, etc...
En concreto veremos tres técnicas que, con algunas diferencias, dan respuesta a nuestro problema.
En la imagen anterior, he señalado en color rojo los registros esperados, que responden a los últimos registros ocurridos para esa dupla: país+producto.
Cargamos la tabla al editor de Power Query.
Y duplicamos en dos ocasiones la consulta creada (hasta tener tres 'queries' iguales.
Las renombraremos como:
-TblORDEN_Opcion1
-TblORDEN_Opcion2
-TblORDEN_Opcion3
En la primera de ellas 'TblORDEN_Opcion1' usaremos la técnica de Quitar duplicados.
Para esto deberemos ordenar adecuadamente nuestros registros...
Por ejemplo ordenando por el campos: 'Orden' (en Descendente!!!, para que los más recientes queden en la parte superior)
Luego Quitaríamos duplicados (en el Editor de Power Query - botón derecho y Quitar duplicados sobre los campos: País & Producto)
La secuencia grabada sería:
En ambos casos el resultado es el correcto:
Fundamental en este caso el empleo de Table.Buffer.
En una entrada posterior explicaremos el por qué.
Otra posible solución la damos en la Opción 2.
Donde los pasos dados serían:
1- Agrupar por 'País' y 'Producto'
2- Modificar algo el código obtenido en Table.Group para conseguir ver el valor máximo del campo Orden
3- Acabar filtrando según las coincidencias obtenidas.
El código completo:
el resultado es el mismo... solo que este método requiere de más tiempo en su ejecución. Especialmente notable con bases de datos grandes...
La opción 3 es una variante de la anterior, pero con un poco de lenguaje M avanzado.
Vemos el código picado:
Tres técnicas interesantes a aplicar según el caso y el volumen de registros...
A partir de nuestra tabla de datos, deseamos recuperar aquellos registros únicos que respondan a un criterio múltiple (País y Producto), pero que hayan sido los últimos en registrarse según un campo de orden, fecha, etc...
En concreto veremos tres técnicas que, con algunas diferencias, dan respuesta a nuestro problema.
En la imagen anterior, he señalado en color rojo los registros esperados, que responden a los últimos registros ocurridos para esa dupla: país+producto.
Cargamos la tabla al editor de Power Query.
Y duplicamos en dos ocasiones la consulta creada (hasta tener tres 'queries' iguales.
Las renombraremos como:
-TblORDEN_Opcion1
-TblORDEN_Opcion2
-TblORDEN_Opcion3
En la primera de ellas 'TblORDEN_Opcion1' usaremos la técnica de Quitar duplicados.
Para esto deberemos ordenar adecuadamente nuestros registros...
Por ejemplo ordenando por el campos: 'Orden' (en Descendente!!!, para que los más recientes queden en la parte superior)
Luego Quitaríamos duplicados (en el Editor de Power Query - botón derecho y Quitar duplicados sobre los campos: País & Producto)
La secuencia grabada sería:
let Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content], Tipo_Cambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}), Filas_Ordenadas = Table.Buffer(Table.Sort(Tipo_Cambiado,{{"Orden", Order.Descending}})), Duplicados_Quitados = Table.Distinct(Filas_Ordenadas, {"País", "Producto"}), Filas_Ordenadas1 = Table.Sort(Duplicados_Quitados,{{"País", Order.Ascending}, {"Producto", Order.Ascending}}) in Filas_Ordenadas1O algo más breve:
let Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content], Tipo_Cambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}), Filas_Ordenadas = Table.Buffer(Table.Sort(Tipo_Cambiado,{{"País", Order.Ascending}, {"Producto", Order.Ascending}})), Duplicados_Quitados = Table.Distinct(Filas_Ordenadas, {"País", "Producto"}) in Duplicados_Quitados
En ambos casos el resultado es el correcto:
Fundamental en este caso el empleo de Table.Buffer.
En una entrada posterior explicaremos el por qué.
Otra posible solución la damos en la Opción 2.
Donde los pasos dados serían:
1- Agrupar por 'País' y 'Producto'
2- Modificar algo el código obtenido en Table.Group para conseguir ver el valor máximo del campo Orden
3- Acabar filtrando según las coincidencias obtenidas.
El código completo:
let Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content], TipoCambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}), //agrupamos por País y Producto //Y definimos que el cálculo a ver sea el dato mayor del campo Orden (List.Max([Orden]) FilasAgrupadas = Table.Group(TipoCambiado, {"País", "Producto"}, {{"Último", each List.Max([Orden]), type number}, {"ListPrecios", each _, type table [Orden=nullable number, País=nullable text, Producto=nullable text, Precio=nullable number]}}, GroupKind.Local), //expandimos la agrupación, y recuperamos de nuevo los campos Orden y Precio SeExpandió_ListPrecios = Table.ExpandTableColumn(FilasAgrupadas, "ListPrecios", {"Orden","Precio"}, {"Orden","Precio"}), //para finalmente, en el conjunto de todas las combinaciones posibles, //quedarnos con aquellos registros donde coincidan Orden y Ultimo Filas_Filtradas = Table.SelectRows(SeExpandió_ListPrecios, each ([Orden] = [Último])), //reordenamos las columnas Columnas_Reordenadas = Table.ReorderColumns(Filas_Filtradas,{"Orden", "País", "Producto", "Precio", "Último"}) in Columnas_Reordenadas
el resultado es el mismo... solo que este método requiere de más tiempo en su ejecución. Especialmente notable con bases de datos grandes...
La opción 3 es una variante de la anterior, pero con un poco de lenguaje M avanzado.
Vemos el código picado:
let Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content], TipoCambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}), //agrupamos por Pais y Producto //sobre los campos resultantes de una tabla filtrada por los registros correspondientes al valor de orden más alto //se consigue ordenando por Descendente el campo Orden, y asignandole un Indice 1, y negativos al posible resto de registros // filtrando solo con aquellos cuyo Indice =1, esto es, el mayor valor FilasAgrupadas = Table.Group( TipoCambiado, {"País", "Producto"}, { {"Último", each Table.SelectRows( [tbl=Table.AddIndexColumn( Table.Sort(_,{{"Orden", Order.Descending}}), "Index", 1, -2, Int64.Type)][tbl] , each ([Index] = 1))} } ), //expandimos la tabla resultante de un solo registro Expande_ListPrecios = Table.ExpandTableColumn(FilasAgrupadas, "Último", {"Orden","Precio"}, {"Orden","Precio"}), //y reordenamos las columnas ColumnasReordenadas = Table.ReorderColumns(Expande_ListPrecios,{"Orden", "País", "Producto", "Precio"}) in ColumnasReordenadas
Tres técnicas interesantes a aplicar según el caso y el volumen de registros...
No hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.