COALESCE https://interactivechaos.ovh/es es Cálculo del número de valores previos a cada fecha https://interactivechaos.ovh/es/dax/scenario/calculo-del-numero-de-valores-previos-cada-fecha <span class="field field--name-title field--type-string field--label-hidden">Cálculo del número de valores previos a cada fecha</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é, 23/06/2021 - 15:10</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 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/2021-06/dax-0110.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-26f2094f-6fc5-4d8f-9cc2-da5576c21073" data-insert-attach="{&quot;id&quot;: &quot;26f2094f-6fc5-4d8f-9cc2-da5576c21073&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/2021-06/dax-0110.jpg" /></a> <p>Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.</p> <p>El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).</p> <p>Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.</p> <p>En pseudo código sería algo así:</p> <div class="codigo">Number of Previous values = <br /> COUNTROWS(<br />     FILTER(<br />         data,<br />         data[Date] &lt; fecha-de-la-fila-actual<br />     )<br /> )</div> <p>Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.</p> <p>La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:</p> <div class="codigo">data[Date] &lt; fecha-de-la-fila-actual</div> <p>Lógicamente, el siguiente código no funcionaría:</p> <div class="codigo">Number of Previous values = <br /> COUNTROWS(<br />     FILTER(<br />         data,<br />         data[Date] &lt; data[Date])<br />     )<br /> )</div> <p>...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.</p> <p>Para ello tenemos dos soluciones:</p> <p>La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:</p> <div class="codigo">Number of Previous values = <br /> COUNTROWS(<br />     FILTER(<br />         data,<br />         data[Date] &lt; EARLIER(data[Date], 1)<br />     )<br /> )</div> <p>...devolvería el resultado que buscábamos:</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"><img alt="Función EARLIER" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-5b76a210-02d1-4484-a8b9-c3a70422d70c" data-insert-attach="{&quot;id&quot;: &quot;5b76a210-02d1-4484-a8b9-c3a70422d70c&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/2021-06/dax-0111.jpg" /></a> <p>Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:</p> <div class="codigo">Number of Previous values = <br /> COALESCE(<br />     COUNTROWS(<br />         FILTER(<br />             data,<br />             data[Date] &lt; EARLIER(data[Date], 1)<br />         )<br />     ),<br />     0<br /> )</div> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"><img alt="Función EARLIER" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-08e7a98a-1bb0-4e89-bba5-5402a6b3a4c0" data-insert-attach="{&quot;id&quot;: &quot;08e7a98a-1bb0-4e89-bba5-5402a6b3a4c0&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/2021-06/dax-0112.jpg" /></a> <p>En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:</p> <div class="codigo">Number of Previous values = <br /> COALESCE(<br />     COUNTROWS(<br />         FILTER(<br />             data,<br />             data[Date] &lt; EARLIEST(data[Date])<br />         )<br />     ),<br />     0<br /> )</div> <p>El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:</p> <div class="codigo">Number of Previous values = <br /> VAR __currentDate = data[Date]<br /> RETURN<br />     COUNTROWS(<br />         FILTER(<br />             data,<br />             data[Date] &lt; __currentDate<br />         )<br />     )</div> <p>En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.</p> <p>Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):</p> <a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"><img alt="Función EARLIER" class="image-colorbox__max_800_px align-center" data-entity-type="file" data-entity-uuid="insert-max_800_px-3cb7ced5-598b-408d-9d7d-d253ab959bba" data-insert-attach="{&quot;id&quot;: &quot;3cb7ced5-598b-408d-9d7d-d253ab959bba&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/2021-06/dax-0113.jpg" /></a> <p>Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.</p> <p>Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:</p> <div class="codigo">Number of Previous values = <br /> VAR __currentDate = data[Date]<br /> RETURN<br />     COALESCE(<br />         COUNTROWS(<br />             FILTER(<br />                 data,<br />                 data[Date] &lt; __currentDate<br />             )<br />         ),<br />         0<br />     )</div> </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/67" hreflang="es">COUNTROWS</a></div> <div class="field__item"><a href="/es/taxonomy/term/48" hreflang="es">FILTER</a></div> <div class="field__item"><a href="/es/taxonomy/term/89" hreflang="es">EARLIER</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/135" hreflang="es">COALESCE</a></div> <div class="field__item"><a href="/es/taxonomy/term/136" hreflang="es">EARLIEST</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, 23 Jun 2021 13:10:10 +0000 admin 3092 at https://interactivechaos.ovh