SUMMARIZE https://interactivechaos.ovh/es es Completado de una tabla sustituyendo valores inexistentes por ceros https://interactivechaos.ovh/es/dax/scenario/completado-de-una-tabla-sustituyendo-valores-inexistentes-por-ceros <span class="field field--name-title field--type-string field--label-hidden">Completado de una tabla sustituyendo valores inexistentes por ceros</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mié, 30/10/2019 - 10:06</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Un caso con el que nos encontramos con cierta frecuencia es aquel en el que tenemos datos tabulares pero no disponemos de valores para todas las combinaciones de filas y columnas, y querríamos tener al menos ceros que nos permitan operar con la tabla completa.</p> <p>Para ver cómo podemos resolver este problema vamos a partir de la siguiente tabla de datos:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0031.jpg"><img alt="Tabla de datos" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-9016ada0-c23b-4f3a-9f90-baed27bfbede" data-insert-attach="{&quot;id&quot;: &quot;9016ada0-c23b-4f3a-9f90-baed27bfbede&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0031.jpg" /></a> <p>Como vemos, se trata de una tabla en la que se muestran las ventas de tres posibles productos a lo largo de los cuatro trimestres del año, tabla en la que muchas de las combinaciones de trimestres y productos no existen.</p> <p>Si, tras leer esta tabla con Power BI, llevamos los datos a una matriz, el resultado es el siguiente:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0032.jpg"><img alt="Matriz de datos en Power BI" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-da07c2cd-781c-4498-99c5-ae1268dfedc7" data-insert-attach="{&quot;id&quot;: &quot;da07c2cd-781c-4498-99c5-ae1268dfedc7&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0032.jpg" /></a> <p>...con blanks en todas aquellas intersecciones de filas y columnas para las que no hay datos en nuestra tabla original.</p> <p>Pues bien, para crear una tabla a partir de la leída que contenga valores en todas las combinaciones de filas y columnas vamos a comenzar identificando los posibles valores en filas y en columnas -lo que podemos conseguir usando la función <a href="https://www.interactivechaos.com/dax/function/values">VALUES</a>-, y calculando el producto cartesiano de ambos conjuntos con <a href="https://www.interactivechaos.com/dax/function/crossjoin">CROSSJOIN</a>:</p> <div class="codigo"> <p>Tabla = <br />     CROSSJOIN(<br />         VALUES(Data[Trimestre]);<br />         VALUES(Data[Producto])<br />     )</p> </div> <p>El resultado se muestra en la siguiente imagen:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0033.jpg"><img alt="Producto cartesiano de los elementos de filas y columnas" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-5bd7eda1-4b9a-4b3d-a94c-2aac29e3ba9d" data-insert-attach="{&quot;id&quot;: &quot;5bd7eda1-4b9a-4b3d-a94c-2aac29e3ba9d&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0033.jpg" /></a> <p>A esta tabla le faltaría la columna de "Ventas" para incluir todos los datos que necesitamos. La añadimos con la función <a href="https://www.interactivechaos.com/dax/function/addcolumns">ADDCOLUMNS</a>:</p> <div class="codigo"> <p>Tabla = <br />     ADDCOLUMNS(<br />         CROSSJOIN(<br />             VALUES(Data[Trimestre]);<br />             VALUES(Data[Producto])<br />         );<br />         "Ventas"; 0<br />     )</p> </div> <p>Ahora ya tenemos la tabla con valores nulos:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0034.jpg"><img alt="Producto cartesiano de los elementos de filas y columnas con ventas" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-d7ba40cb-dc01-44b3-b5fe-c30e201170cf" data-insert-attach="{&quot;id&quot;: &quot;d7ba40cb-dc01-44b3-b5fe-c30e201170cf&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0034.jpg" /></a> <p>Si llevamos esta tabla a una matriz confirmamos que el aspecto es el deseado:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0035.jpg"><img alt="Matriz con los datos de la nueva tabla" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-7fc1cafc-e2c1-450c-8262-aabd0fc9bc07" data-insert-attach="{&quot;id&quot;: &quot;7fc1cafc-e2c1-450c-8262-aabd0fc9bc07&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0035.jpg" /></a> <p>Ahora necesitamos "sumar" los valores de ambas tablas, la original y la que acabamos de crear. Para ello vamos a recurrir a unirlas (verticalmente) con la función <a href="https://www.interactivechaos.com/dax/function/union">UNION</a>:</p> <div class="codigo"> <p>Tabla = <br />     VAR <br />         tabla1 = ADDCOLUMNS(<br />                 CROSSJOIN(<br />                     VALUES(Data[Trimestre]);<br />                     VALUES(Data[Producto])<br />                 );<br />                 "Ventas"; 0<br />             )<br />     VAR<br />         tabla2 = Data<br />     RETURN<br />         UNION(<br />             tabla1;<br />             tabla2<br />         )</p> </div> <p>El resultado es el siguiente:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0036.jpg"><img alt="Unión de las dos tablas" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-3b4d3fbb-bba0-4819-b6f9-e5dd0ffb343f" data-insert-attach="{&quot;id&quot;: &quot;3b4d3fbb-bba0-4819-b6f9-e5dd0ffb343f&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0036.jpg" /></a> <p>Como nuestro objetivo es tener una tabla con una única entrada para cada combinación de filas y columnas, la agregamos según estos criterios. El problema con el que nos encontramos aquí es que la función <a href="https://www.interactivechaos.com/dax/function/summarize">SUMMARIZE</a>, por ejemplo, exige una tabla de base, no una tabla calculada. De forma que vamos a crear una nueva tabla calculada a partir de la anterior:</p> <div class="codigo"> <p>Tabla completa = <br />     SUMMARIZE(<br />         Tabla;<br />         Tabla[Trimestre];<br />         Tabla[Producto];<br />         "Ventas"; SUM(Tabla[Ventas])<br />     )</p> </div> <p>El resultado es el esperado:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0037.jpg"><img alt="Tabla agregada" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-6dd2737f-9cb0-49d2-8d60-d0246e5d4689" data-insert-attach="{&quot;id&quot;: &quot;6dd2737f-9cb0-49d2-8d60-d0246e5d4689&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0037.jpg" /></a> <p>Ahora ya podemos llevar esta tabla a una matriz y comprobar que incluye todos los valores:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2019-10/dax-0038.jpg"><img alt="Matriz con los datos agregados" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-d6e78bb0-18ba-410b-81e2-b14e9c8533d9" data-insert-attach="{&quot;id&quot;: &quot;d6e78bb0-18ba-410b-81e2-b14e9c8533d9&quot;, &quot;attributes&quot;: {&quot;alt&quot;: [&quot;alt&quot;, &quot;description&quot;], &quot;title&quot;: [&quot;title&quot;]}}" data-insert-class="" data-insert-type="image" src="/sites/default/files/styles/max_800_px/public/2019-10/dax-0038.jpg" /></a></div> <div class="field field--name-field-funciones-dax-involucradas field--type-entity-reference field--label-above"> <div class="field__label">Funciones DAX involucradas</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/term/80" hreflang="es">CROSSJOIN</a></div> <div class="field__item"><a href="/es/taxonomy/term/30" hreflang="es">VALUES</a></div> <div class="field__item"><a href="/es/taxonomy/term/84" hreflang="es">ADDCOLUMNS</a></div> <div class="field__item"><a href="/es/taxonomy/term/68" hreflang="es">VAR</a></div> <div class="field__item"><a href="/es/taxonomy/term/75" hreflang="es">UNION</a></div> <div class="field__item"><a href="/es/taxonomy/term/51" hreflang="es">SUMMARIZE</a></div> <div class="field__item"><a href="/es/taxonomy/term/28" hreflang="es">SUM</a></div> </div> </div> Wed, 30 Oct 2019 09:06:37 +0000 admin 1662 at https://interactivechaos.ovh Obtención de los datos de ventas relativos a los 10 productos con mayores ventas https://interactivechaos.ovh/es/dax/scenario/obtencion-de-los-datos-de-ventas-relativos-los-10-productos-con-mayores-ventas <span class="field field--name-title field--type-string field--label-hidden">Obtención de los datos de ventas relativos a los 10 productos con mayores ventas</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 28/07/2019 - 12:17</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>En este escenario partimos de una tabla de ventas ("<em>Sales</em>") y otra con información sobre los productos ("<em>Products</em>"). En la primera tenemos un campo que indica el producto vendido y otro ("<em>Amount</em>") con la cifra de venta. En la tabla de productos tenemos un campo ("<em>Product name</em>") con el nombre del producto. Obviamente, ambas tablas están relacionadas a través de un campo que contiene el identificador de cada producto.</p> <p>El objetivo es la creación de una tabla que contenga toda la información de ventas para los 10 productos con mayores ventas (es decir, queremos un subconjunto de la tabla de ventas <em>Sales</em> que contenga información solo de los 10 productos más vendidos). Este escenario es semejante al de <a href="/dax/scenario/obtencion-de-los-10-clientes-que-mas-compras-acumulan">Obtención de los 10 clientes que más compras acumulan</a>, salvo por el hecho de que, aquí, no queremos un simple listado de productos con sus cifras de ventas, sino toda la información de ventas relativa a dichos productos.</p> <p>El plan es sencillo: Generamos una tabla de ventas totales por cada producto, seleccionamos los 10 con mayores cifras y utilizamos esta información para filtrar la tabla original de ventas de forma que solo incluya datos para dichos productos.</p> <p>Comencemos con la primera de las tablas: la agregación de ventas por producto. Para ello recurrimos a la función <a href="/dax/function/summarize">SUMMARIZE</a>, especificando como campo de agregación <em>Products[Product name]</em> y como columna a crear la resultante de aplicar la función <a href="/dax/function/sum">SUM</a> al campo <em>Sales[Amount]:</em></p> <div class="codigo"> <p>10 productos más vendidos = <br />     VAR<br />         VentasPorProducto =<br />             SUMMARIZE(<br />                 Sales;<br />                 Products[Product name];<br />                 "Sales"; SUM(Sales[Amount])<br />             )<br />     RETURN<br />         VentasPorProducto</p> </div> <img alt="Tabla agregada de total de ventas por producto" data-entity-type="file" data-entity-uuid="380d4e69-2687-4abc-a532-496e93fe4d2c" src="/sites/default/files/inline-images/dax-0002.png" class="align-center" width="402" height="438" loading="lazy" /><p>Como puede verse, se ha llevado la expresión a una variable para poder seguir completando la tabla calculada.</p> <p>Ahora queremos quedarnos solamente con los 10 productos con mayores ventas, para lo que recurrimos a la función <a href="/dax/function/topn">TOPN</a>. Como tabla de partida indicamos la anteriormente obtenida y como expresión, el campo <em>Sales</em> creado:</p> <div class="codigo"> <p>10 productos más vendidos = <br />     VAR<br />         VentasPorProducto =<br />             SUMMARIZE(<br />                 Sales;<br />                 Products[Product name];<br />                 "Sales"; SUM(Sales[Amount])<br />             )<br />     VAR<br />         ProductosMasVendidos =<br />             TOPN(<br />                 10;<br />                 VentasPorProducto;<br />                 [Sales]<br />             )<br />     RETURN<br />         ProductosMasVendidos</p> </div> <img alt="Tabla de los 10 productos más vendidos" data-entity-type="file" data-entity-uuid="03d644f3-2f19-4daa-b993-832d31ba74bf" src="/sites/default/files/inline-images/dax-0003.png" class="align-center" width="407" height="558" loading="lazy" /><p>Por último queremos utilizar esta tabla para filtrar la tabla de ventas, <em>Sales</em>. Para ello vamos a utilizar la función <a href="/dax/function/naturalinnerjoin">NATURALINNERJOIN</a> para crear una combinación natural entre la tabla de ventas y la tabla generada con los productos más vendidos. Al tratarse de una combinación natural interna, solo se mantendrán los registros que compartan los mismos valores en el campo o campos comunes. El campo común es <em>Product Name</em> (en el caso de la tabla <em>Sales</em>, el campo viene dado por su relación con la tabla <em>Products</em>). El código es el siguiente:</p> <div class="codigo"> <p>10 productos más vendidos = <br />     VAR<br />         VentasPorProducto =<br />             SUMMARIZE(<br />                 Sales;<br />                 Products[Product name];<br />                 "Sales"; SUM(Sales[Amount])<br />             )<br />     VAR<br />         ProductosMasVendidos =<br />             TOPN(<br />                 10;<br />                 VentasPorProducto;<br />                 [Sales]<br />             )<br />     RETURN<br />         NATURALINNERJOIN(<br />             Sales;<br />             ProductosMasVendidos<br />         )</p> </div> <p>...y el resultado es el que podemos ver en la siguiente imagen:</p> <img alt="Tabla resultante de la combinación natural interna" data-entity-type="file" data-entity-uuid="548c9793-7802-4047-a9bc-34fdf7c4bf6d" src="/sites/default/files/inline-images/dax-0004.png" class="align-center" width="708" height="555" loading="lazy" /><p>Vemos que se incluyen los campos de ambas tablas. Podríamos seleccionar solo los campos de interés con <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a>, por ejemplo.</p> </div> <div class="field field--name-field-funciones-dax-involucradas field--type-entity-reference field--label-above"> <div class="field__label">Funciones DAX involucradas</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/term/68" hreflang="es">VAR</a></div> <div class="field__item"><a href="/es/taxonomy/term/51" hreflang="es">SUMMARIZE</a></div> <div class="field__item"><a href="/es/taxonomy/term/28" hreflang="es">SUM</a></div> <div class="field__item"><a href="/es/taxonomy/term/55" hreflang="es">TOPN</a></div> <div class="field__item"><a href="/es/taxonomy/term/98" hreflang="es">NATURALINNERJOIN</a></div> </div> </div> Sun, 28 Jul 2019 10:17:30 +0000 admin 1202 at https://interactivechaos.ovh Agregación de dos tablas con la misma estructura https://interactivechaos.ovh/es/dax/scenario/agregacion-de-dos-tablas-con-la-misma-estructura <span class="field field--name-title field--type-string field--label-hidden">Agregación de dos tablas con la misma estructura</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mié, 10/04/2019 - 10:58</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Un escenario frecuente y sencillo de resolver es aquel en el que nos encontramos con dos tablas de idéntica estructura que deseamos agregar según algún campo. Veamos cómo sería. Suponemos que ya hemos obtenido los datos y tenemos cargadas en Power BI las dos tablas que, en este caso, contienen información de ventas:</p> <img alt="Tabla 1" data-entity-type="file" data-entity-uuid="46d7b1ed-8bab-4fc1-8789-cbe6657b8ca5" src="/sites/default/files/inline-images/escenario-dax-0010.PNG" class="align-center" width="690" height="158" loading="lazy" /><img alt="Tabla 2" data-entity-type="file" data-entity-uuid="5c8295a5-d833-4a35-bf57-35e69a3f3cff" src="/sites/default/files/inline-images/escenario-dax-0011.PNG" class="align-center" width="698" height="157" loading="lazy" /><p>En este escenario queremos obtener el total de ventas por vendedor. Vamos a hacerlo en dos fases:</p> <ol><li>Unión de las tablas anteriores</li> <li>Agregación de la tabla completa para mostrar las ventas (campo "<em>Precio final</em>") según el campo que identifica cada vendedor</li> </ol><p>Para el primer paso vamos a recurrir a la función <a href="/es/dax/function/union">UNION</a>. Sin embargo, no vamos a unir las tablas directamente pues, como vemos en las imágenes anteriores, a pesar de tener la misma estructura (y, en el editor de consultas, aparecer con las columnas en el mismo orden) cuando se importan a Power BI las columnas no se muestran en el mismo orden (probablemente por un <em>bug</em> en el software que existe desde, al menos, finales de 2017). Es por ello que vamos a aplicar la función UNION a las tablas especificando a mano las columnas que nos interesan y el orden que nos interesa, para lo que recurriremos a la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>:</p> <div class="codigo"> <p>Ventas totales = <br />     VAR<br />         Tabla1 = SELECTCOLUMNS(<br />             Ventas1;<br />             "Vendedor"; Ventas1[Id Vendedor];<br />             "PVP"; Ventas1[Precio final]<br />         )<br />     VAR<br />         Tabla2 = SELECTCOLUMNS(<br />             Ventas2;<br />             "Vendedor"; Ventas2[Id Vendedor];<br />             "PVP"; Ventas2[Precio final]<br />         )<br />     RETURN<br />         UNION(Tabla1; Tabla2)</p> </div> <img alt="Ventas totales" data-entity-type="file" data-entity-uuid="2e9813ee-d18b-47e7-bc9f-46a4586d92a6" src="/sites/default/files/inline-images/escenario-dax-0012.PNG" class="align-center" width="164" height="282" loading="lazy" /><p>Hemos seleccionado apenas las columnas "Vendedor" y "Precio final" (con el nombre de "PVP") pero podríamos haber seleccionado otras columnas también.</p> <p>Ahora, para el segundo paso, utilizamos la función <a href="/es/dax/function/summarize">SUMMARIZE</a> para agregar la tabla anterior:</p> <div class="codigo"> <p>Ventas totales por vendedor = <br />     SUMMARIZE(<br />         'Ventas totales';<br />         'Ventas totales'[Vendedor];<br />         "Ventas"; SUM('Ventas totales'[PVP]<br />         )<br />     )</p> </div> <img alt="Tabla de ventas agregada por vendedor" data-entity-type="file" data-entity-uuid="44dad59e-f058-470f-9c22-ceb2790c4512" src="/sites/default/files/inline-images/escenario-dax-0013.PNG" class="align-center" width="163" height="94" loading="lazy" /></div> <div class="field field--name-field-funciones-dax-involucradas field--type-entity-reference field--label-above"> <div class="field__label">Funciones DAX involucradas</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/term/75" hreflang="es">UNION</a></div> <div class="field__item"><a href="/es/taxonomy/term/69" hreflang="es">SELECTCOLUMNS</a></div> <div class="field__item"><a href="/es/taxonomy/term/51" hreflang="es">SUMMARIZE</a></div> <div class="field__item"><a href="/es/taxonomy/term/28" hreflang="es">SUM</a></div> </div> </div> <div class="field field--name-field-dax-esc-dificultad field--type-list-string field--label-above"> <div class="field__label">Dificultad</div> <div class="field__item">Intermedia</div> </div> Wed, 10 Apr 2019 08:58:12 +0000 admin 1046 at https://interactivechaos.ovh Suma de los valores máximos de cada categoría https://interactivechaos.ovh/es/dax/scenario/suma-de-los-valores-maximos-de-cada-categoria <span class="field field--name-title field--type-string field--label-hidden">Suma de los valores máximos de cada categoría</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mar, 08/01/2019 - 19:19</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría:</p> <img alt="Datos de partida" data-entity-type="file" data-entity-uuid="96494bcb-fe75-421b-8f87-db56ee6f1d2b" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_01.JPG" class="align-center" width="159" height="220" loading="lazy" /><p>El objetivo es calcular el valor máximo de cada categoría (7 para la categoría A, 3 para B y 8 para C) y sumarlos (18 en este caso).</p> <p>La resolución de este escenario incluye dos pasos:</p> <p>1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente:</p> <img alt="Tabla intermedia con los valores máximos por categoría" data-entity-type="file" data-entity-uuid="df216c47-c8c0-41eb-ab0a-991917599a9d" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_02.JPG" class="align-center" width="197" height="93" loading="lazy" /><p>2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados.</p> <h3>1er paso</h3> <p>Para crear esta tabla intermedia podemos recurrir tanto a la función <a href="/dax/function/summarize">SUMMARIZE</a> como a <a href="/dax/function/summarizecolumns">SUMMARIZECOLUMNS</a> o <a href="/dax/function/groupby">GROUPBY</a>. Veamos los tres casos:</p> <h4>SUMMARIZE</h4> <p>El código sería el siguiente:</p> <div class="codigo"> <p>Max value per category summarize =</p> <p>    SUMMARIZE(</p> <p>        Data;</p> <p>        Data[Category];</p> <p>        "Max value"; MAX(Data[Value])</p> <p>    )</p> </div> <p>Básicamente estaríamos agregando el campo <em>Category</em> de la tabla <em>Data</em> para crear el campo <em>"Max value"</em> calculando el valor máximo del campo <em>Data[Value]</em> con la función <a href="/dax/function/max">MAX</a> una vez filtrado:</p> <img alt="Cálculo de la tabla intermedia con la función SUMMARIZE" data-entity-type="file" data-entity-uuid="3acd4fe9-c39b-4752-8526-ede313a7b2a0" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_03.JPG" class="align-center" width="380" height="215" loading="lazy" /><h4>SUMMARIZECOLUMNS</h4> <p>En este segundo caso el código sería el siguiente:</p> <div class="codigo"> <p>Max value per category summarizecolumns =</p> <p>    SUMMARIZECOLUMNS(</p> <p>    Data[Category];</p> <p>    "Max value";</p> <p>    MAX(Data[Value])</p> <p>)</p> </div> <img alt="Cálculo de la tabla intermedia con la función SUMMARIZECOLUMNS" data-entity-type="file" data-entity-uuid="7b547472-d0c6-41d8-8711-3a5192760aee" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_04.JPG" class="align-center" width="393" height="215" loading="lazy" /><p>Estamos agregando el campo <em>Data[Category]</em> y creando el nuevo campo <em>"Max value"</em> calculando el valor máximo del campo <em>Data[Value]</em> una vez filtrado, también con la función <a href="/dax/function/max">MAX</a>.</p> <h4>GROUPBY</h4> <p>Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma:</p> <div class="codigo"> <p>Max value per category groupby =</p> <p>GROUPBY(</p> <p>    Data;</p> <p>    Data[Category];</p> <p>    "Max value"; MAXX(CURRENTGROUP(); Data[Value])</p> <p>    )</p> </div> <p>En este caso estamos agrupando la tabla <em>Data</em> según la columna <em>Data[Category]</em> y generando la columna "<em>Max value</em>" utilizando la función iterativa <a href="/dax/function/maxx">MAXX</a>. </p> <img alt="Cálculo de la tabla intermedia con la función GROUPBY" data-entity-type="file" data-entity-uuid="390dbbbf-8984-403f-8733-8d3ee69b5dc7" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_05.JPG" class="align-center" width="469" height="218" loading="lazy" /><h3>2º paso</h3> <p>Una vez conseguida la tabla anterior usando cualquiera de los tres métodos (supongamos que usando la función <em>GROUPBY</em>), tendremos que volver a agregar la tabla sumando los valores de la columna <em>"Max value"</em>. En este paso, al contrario que en el paso anterior, no todas las funciones mencionadas servirían. Veámoslas una a una:</p> <h4>SUMMARIZE</h4> <p>El código para esta primera función sería el siguiente:</p> <div class="codigo"> <p>Sum of max value per category = <br />     SUMMARIZE(<br />         'Max value per category groupby';<br />         "Max"; SUM('Max value per category groupby'[Max value])<br />     )</p> </div> <p>Es decir, estaríamos agregando la tabla intermedia creada, <em>Max value per category groupby</em>, sin especificar el campo de agregación (pues no queremos más que la suma) y el nuevo campo a crear, <em>Max</em>, como la suma de los valores. El resultado sería el mostrado en la siguiente imagen:</p> <img alt="Cálculo del resultado final con la función SUMMARIZE" data-entity-type="file" data-entity-uuid="79fc6517-49bf-471c-b440-a221ce20a369" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_06.JPG" class="align-center" width="535" height="158" loading="lazy" /><p>Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos.</p> <p>Obsérvese, en todo caso, que con esta función, SUMMARIZE, no sería posible crear la tabla intermedia y realizar la agregación en una única expresión DAX, pues la función SUMMARIZE devuelve un error ("se espera una tabla de base")</p> <h4>SUMMARIZECOLUMNS</h4> <p>Con esta función, el código sería el siguiente:</p> <div class="codigo"> <p>Sum of max value per category = <br />     SUMMARIZECOLUMNS(<br />         "Max"; SUM('Max value per category groupby'[Max value])<br />     )</p> </div> <p>Estamos agregando la tabla intermedia creada, nuevamente sin especificar el campo de agregación, y creando el campo <em>Max</em> como la suma del campo <em>Max value</em> de la tabla intermedia. El resultado es el siguiente:</p> <img alt="Cálculo del resultado final con la función SUMMARIZECOLUMNS" data-entity-type="file" data-entity-uuid="ed2d8e78-9985-4165-8118-f0824d06bd9b" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_07.JPG" class="align-center" width="536" height="163" loading="lazy" /><p>Al igual que ocurre con SUMMARIZE, el intento de aplicar la función SUMMARIZECOLUMNS a una tabla intermedia creada en la misma expresión DAX devolvería un error.</p> <h4>GROUPBY</h4> <p>En este último caso, el código sería el siguiente:</p> <div class="codigo"> <p>Sum of max value per category = <br />     VAR Max_value_per_category =<br />         GROUPBY(<br />             Data;<br />             Data[Category];<br />             "Max value"; MAXX(CURRENTGROUP(); Data[Value])<br />         )<br />     RETURN<br />         GROUPBY(<br />             Max_value_per_category;<br />             "Sum"; SUMX(CURRENTGROUP(); [Max value])<br />         )</p> </div> <p>Estaríamos simplemente agregando la tabla intermedia generando como resultado la suma de los valores <em>Max value</em> de forma iterativa. El resultado es el siguiente:</p> <img alt="Cálculo del resultado final con la función GROUPBY" data-entity-type="file" data-entity-uuid="d918aa2a-faf7-41b9-9eab-c48896db8378" src="/sites/default/files/inline-images/dax_scenario_suma_maximos_cat_08.JPG" class="align-center" width="501" height="280" loading="lazy" /><p>En este tercer caso, sí es posible crear la tabla intermedia en la misma expresión DAX, lo que hace de esta función la más adecuada para este escenario.</p> </div> <div class="field field--name-field-funciones-dax-involucradas field--type-entity-reference field--label-above"> <div class="field__label">Funciones DAX involucradas</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/term/51" hreflang="es">SUMMARIZE</a></div> <div class="field__item"><a href="/es/taxonomy/term/59" hreflang="es">MAX</a></div> <div class="field__item"><a href="/es/taxonomy/term/39" hreflang="es">MAXX</a></div> <div class="field__item"><a href="/es/taxonomy/term/28" hreflang="es">SUM</a></div> <div class="field__item"><a href="/es/taxonomy/term/61" hreflang="es">SUMX</a></div> <div class="field__item"><a href="/es/taxonomy/term/58" hreflang="es">SUMMARIZECOLUMNS</a></div> <div class="field__item"><a href="/es/taxonomy/term/60" hreflang="es">GROUPBY</a></div> <div class="field__item"><a href="/es/taxonomy/term/68" hreflang="es">VAR</a></div> </div> </div> Tue, 08 Jan 2019 18:19:22 +0000 admin 356 at https://interactivechaos.ovh Número de ventas por día de la semana según el día de venta y el día de envío https://interactivechaos.ovh/es/dax/scenario/numero-de-ventas-por-dia-de-la-semana-segun-el-dia-de-venta-y-el-dia-de-envio <span class="field field--name-title field--type-string field--label-hidden">Número de ventas por día de la semana según el día de venta y el día de envío</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 06/01/2019 - 17:17</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>En este escenario partimos de una tabla de ventas, <em>Sales</em>, en la que se incluye un campo con la referencia del día de la orden de venta, <em>OrderDateKey</em>, y otro con la referencia del día del envío del producto, <em>ShipDateKey</em>. Hay, por supuesto, una tabla conteniendo el calendario, <em>Calendar</em> en la que se especifica el día de la semana de cada fecha en el campo <em>DayName</em>. Entre ambas tablas, <em>Sales</em> y <em>Calendar</em>, existe una relación de tipo muchos a uno entre los campos <em>OrderDateKey </em>y <em>DateKey</em>, respectivamente.</p> <p>El objetivo es averiguar cuántas ventas se realizan por día de la semana y cuántos envíos de productos se realizan por día de la semana.</p> <p>Podríamos pensar que para esto bastaría generar sendas tablas con visualizaciones llevando a éstas el campo <em>'Calendar'[DayName]</em> (a ambas tablas) y los campos <em>OrderDateKey </em>y <em>ShipDateKey</em> de la tabla <em>Sales</em> (un campo a cada tabla), asegurándonos de que se aplique un recuento sobre estos últimos dos campos. El resultado sería el siguiente:</p> <img alt="Visualizaciones con el número de ventas y envíos por día de la semana" data-entity-type="file" data-entity-uuid="f128504b-25ee-439e-b5e9-54ad261050fe" src="/sites/default/files/inline-images/dax_scenario_ventas_por_dia_semana_01.jpg" class="align-center" width="566" height="267" loading="lazy" /><p>Aun cuando los días no se muestran en orden, comprobamos que ambas visualizaciones muestran exactamente la misma información, lo que no es coherente con los datos de los que disponemos. El motivo de este aparente error es que ambas visualizaciones son generadas utilizando la misma relación entre las dos tablas -la relación que une los ya mencionados campos <em>Sales[OrderDateKey]</em> y <em>Calendar[DateKey]-</em> por lo que, con independencia del campo del que partamos en la tabla <em>Sales</em> (<em>OrderDateKey</em> o <em>ShipDateKey</em>), el registro de destino en la tabla <em>Calendar</em> es siempre el mismo y, consecuentemente, el día de la semana asignado es también el mismo.</p> <p>Lo que necesitamos es crear estas tablas utilizando dos relaciones distintas: una -la que utilizaremos para generar la tabla con el número de ventas según el día en que ésta se realiza- será la relación que ya existe entre los campos <em>Sales[OrderDate]</em> y <em>Calendar[DateKey]</em>. La segunda -a usar en la tabla que incluirá información relativa al número de envíos por día de la semana- deberá unir los campos <em>Sales[ShipDateKey]</em> y <em>Calendar[DateKey].</em></p> <p>Creamos, por lo tanto, esta segunda relación entre las tablas <em>Sales</em> y <em>Calendar</em>. Como solo puede existir una relación activa entre dos tablas, esta segunda relación se mostrará desactivada, aunque podrá ser utilizada en las funciones DAX que la requieran:</p> <img alt="Segunda relación entre las tablas de ventas y el calendario" data-entity-type="file" data-entity-uuid="98de9281-933c-4b25-9406-4c1639992fd0" src="/sites/default/files/inline-images/dax_scenario_ventas_por_dia_semana_02.jpg" class="align-center" width="742" height="479" loading="lazy" /><p>Vamos a generar a continuación las dos tablas utilizando la función <a href="/dax/function/summarize">SUMMARIZE</a>, Esta función nos permitirá resumir el campo de fecha que nos interese de la tabla de ventas (realizando un recuento del mismo) para cada uno de los valores que tome el campo remoto <em>Calendar[DayName]</em>. Así, para la tabla que deberá mostrar el número de órdenes de venta por día de la semana, la función a utilizar sería:</p> <div class="codigo"> <p>Tabla intermedia = SUMMARIZE(</p> <p>    Sales;</p> <p>    'Calendar'[DayName];</p> <p>    "Number of orders"; COUNT(Sales[OrderDateKey])</p> <p>);</p> </div> <p>Es decir, estaríamos generando una tabla a partir de la tabla <em>Sales</em>, agrupando los resultados por los valores del campo remoto <em>'Calendar'[DayName]</em> y totalizando el campo <em>Sales[OrderDateKey]</em> contando sus registros y dando a este campo de agregación, en este ejemplo, el nombre <em>Number of orders</em>.</p> <p>Para la primera de las tablas a generar, esto ya sería suficiente. Pero vamos a generalizar el resultado para poder aplicar el mismo código a la segunda tabla a generar sin tener que realizar grandes modificaciones. Para esto tendríamos que añadir al código generado la opción de especificar la relación a usar, para lo que utilizaremos la función <a href="/dax/function/userelationship">USERELATIONSHIP</a>. Esta función se aplica como un filtro a una tabla, por lo que podemos recurrir a la función <a href="/dax/function/calculatetable">CALCULATETABLE</a> para modificar la tabla intermedia con el filtro en cuestión. El código sería algo como:</p> <div class="codigo"> <p>Tabla final = CALCULATETABLE(</p> <p>    Tabla intermedia;</p> <p>    USERELATIONSHIP(relación-a-usar)</p> <p>)</p> </div> <p>El código para generar la primera tabla (recordemos que es la tabla que muestra el número de órdenes de venta por día de la semana) sería, por lo tanto:</p> <div class="codigo"> <p>Number of order dates per day of week =</p> <p>    CALCULATETABLE(</p> <p>        SUMMARIZE(</p> <p>        Sales;</p> <p>        'Calendar'[DayName];</p> <p>        "Number of order dates"; COUNT(Sales[OrderDateKey])</p> <p>    );</p> <p>    USERELATIONSHIP(Sales[OrderDateKey]; 'Calendar'[DateKey])</p> <p>)</p> </div> <p>La relación a usar es la activa, por lo que, tal y como se ha dicho, esta parte es redundante. Pero nos permite generar la segunda tabla con una mínima modificación del código:</p> <div class="codigo"> <p>Number of ship dates per day of week =</p> <p>    CALCULATETABLE(</p> <p>        SUMMARIZE(</p> <p>        Sales;</p> <p>        'Calendar'[DayName];</p> <p>        "Number of ship dates"; COUNT(Sales[ShipDateKey])</p> <p>        );</p> <p>        USERELATIONSHIP(Sales[ShipDateKey]; 'Calendar'[DateKey])</p> <p>    )</p> </div> <p>En esta segunda versión, la única diferencia es el origen de la relación a usar: <em>Sales[ShipDateKey]</em> en lugar del campo por defecto <em>Sales[OrderDateKey]</em>.</p> <p>Las tablas generadas podrían ser usada en nuevos cálculos pero, en este ejemplo, vamos a crear tablas calculadas. Para la primera el resultado sería el siguiente:</p> <img alt="Número de órdenes de venta por día de la semana" data-entity-type="file" data-entity-uuid="b1a04b30-5291-4893-a67e-f63ba97d58c6" src="/sites/default/files/inline-images/dax_scenario_ventas_por_dia_semana_03.jpg" class="align-center" width="463" height="463" loading="lazy" /><p>Y para la segunda sería el siguiente:</p> <img alt="Número de envíos por día de la semana" data-entity-type="file" data-entity-uuid="34c3d0ca-e85c-43ef-98b7-7a614efafe4e" src="/sites/default/files/inline-images/dax_scenario_ventas_por_dia_semana_04.jpg" class="align-center" width="468" height="466" loading="lazy" /><p>Comprobamos ahora cómo ambas tablas muestran información diferente, tal y como era de esperar.</p> </div> <div class="field field--name-field-funciones-dax-involucradas field--type-entity-reference field--label-above"> <div class="field__label">Funciones DAX involucradas</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/term/51" hreflang="es">SUMMARIZE</a></div> <div class="field__item"><a href="/es/taxonomy/term/52" hreflang="es">COUNT</a></div> <div class="field__item"><a href="/es/taxonomy/term/53" hreflang="es">CALCULATETABLE</a></div> <div class="field__item"><a href="/es/taxonomy/term/54" hreflang="es">USERELATIONSHIP</a></div> </div> </div> Sun, 06 Jan 2019 16:17:08 +0000 admin 351 at https://interactivechaos.ovh Obtención de los 10 clientes que más compras acumulan https://interactivechaos.ovh/es/dax/scenario/obtencion-de-los-10-clientes-que-mas-compras-acumulan <span class="field field--name-title field--type-string field--label-hidden">Obtención de los 10 clientes que más compras acumulan</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Vie, 04/01/2019 - 10:39</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>En este escenario partimos de una tabla de ventas (<em>Sales</em>) que contiene, entre otros campos, la clave que identifica cada cliente (<em>CustomerKey</em>) y el monto involucrado en cada compra (<em>SalesAmount</em>). El objetivo es generar una tabla (que puede ser añadida al modelo de datos o tratada como argumento en otras funciones) que incluya los 10 clientes que más compras acumulan. En este ejemplo concreto se creará una tabla calculada con esta información.</p> <p>El proceso a seguir es:</p> <ol><li>Obtención de una tabla que resuma las compras por cliente</li> <li>Ordenación y filtrado de dicha tabla para extraer apenas los 10 mayores</li> </ol><p>Para la obtención de la tabla recurrimos a la función <a href="/dax/function/summarize">SUMMARIZE</a>:</p> <div class="codigo"> <p>VAR SalesByCustomer =</p> <p>    SUMMARIZE(</p> <p>        Sales;</p> <p>        Sales[CustomerKey];</p> <p>        "Total spent"; SUM(Sales[SalesAmount])</p> <p>    )</p> </div> <p>Estamos resumiendo la tabla <em>Sales</em>, agrupándola por el campo <em>CustomerKey</em> y totalizando, para cada <em>CustomerKey</em>, la suma de las ventas.</p> <p>A continuación no queda más que extraer los 10 valores de CustomerKey que más ventas acumulan, para lo que recurrimos a la función <a href="/dax/function/topn">TOPN</a>:</p> <div class="codigo"> <p>VAR SummaryTableFiltered =</p> <p>    TOPN(</p> <p>        10;</p> <p>        SalesByCustomer;</p> <p>        [Total spent]</p> <p>    )</p> </div> <p>Extraemos 10 registros de la tabla creada en el paso anterior, <em>SalesByCustomer</em>, tomando como criterio el campo <em>Total spent</em>. Obsérvese que éste campo ha sido también creado en el paso anterior.</p> <p>Por último, no queda más que dar un nombre a la tabla que estamos creando (<em>Top 10 customers</em>) y devolver el resultado. El código final es el siguiente:</p> <div class="codigo"> <p>Top 10 customers =</p> <p>    VAR SalesByCustomer =</p> <p>        SUMMARIZE(</p> <p>            Sales;</p> <p>            Sales[CustomerKey];</p> <p>            "Total spent"; SUM(Sales[SalesAmount])</p> <p>        )</p> <p>    VAR SummaryTableFiltered =</p> <p>        TOPN(</p> <p>            10;</p> <p>            SalesByCustomer;</p> <p>            [Total spent]</p> <p>        )</p> <p>    RETURN SummaryTableFiltered</p> </div> <img alt="Obtención de los 10 clientes que más compras acumulan" data-entity-type="file" data-entity-uuid="cdc763c3-0537-490d-9ad5-71546c8b3837" src="/sites/default/files/inline-images/dax_scenario_top_10_customers_01.jpg" class="align-center" width="450" height="502" loading="lazy" /><p> </p> </div> <div class="field field--name-field-funciones-dax-involucradas field--type-entity-reference field--label-above"> <div class="field__label">Funciones DAX involucradas</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/term/51" hreflang="es">SUMMARIZE</a></div> <div class="field__item"><a href="/es/taxonomy/term/28" hreflang="es">SUM</a></div> <div class="field__item"><a href="/es/taxonomy/term/55" hreflang="es">TOPN</a></div> <div class="field__item"><a href="/es/taxonomy/term/68" hreflang="es">VAR</a></div> </div> </div> Fri, 04 Jan 2019 09:39:44 +0000 admin 339 at https://interactivechaos.ovh