Cálculo del número de días entre compras
Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras:
Drupal\user\Entity\Role::postLoad(Object, Array) (Line: 423) Drupal\Core\Entity\EntityStorageBase->postLoad(Array) (Line: 353) Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 16) Drupal\user\RoleStorage->isPermissionInRoles('access site in maintenance mode', Array) (Line: 112) Drupal\Core\Session\UserSession->hasPermission('access site in maintenance mode') (Line: 105) Drupal\Core\Session\AccountProxy->hasPermission('access site in maintenance mode') (Line: 83) Drupal\redirect\RedirectChecker->canRedirect(Object) (Line: 120) Drupal\redirect\EventSubscriber\RedirectRequestSubscriber->onKernelRequestCheckRedirect(Object, 'kernel.request', Object) call_user_func(Array, Object, 'kernel.request', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.request') (Line: 145) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54) Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 141) Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104) Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82) Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 2318) Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697) Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54) Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228) Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 144) Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104) Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82) Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 2318) Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697) Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54) Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228) Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 110) Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82) Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 2318) Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697) Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 35) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 2318) Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697) Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('views') (Line: 1316) Drupal\views\Plugin\views\query\Sql->query() (Line: 1454) Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('views_substitutions', Array) (Line: 1418) Drupal\views\Plugin\views\query\Sql->query() (Line: 1454) Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('views') (Line: 1316) Drupal\views\Plugin\views\query\Sql->query(1) (Line: 1455) Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('views_substitutions', Array) (Line: 1418) Drupal\views\Plugin\views\query\Sql->query(1) (Line: 1455) Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54) Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 141) Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104) Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82) Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 1876) Drupal\views\ViewExecutable->buildTitle() (Line: 338) Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733) Drupal\views\ViewExecutable->attachDisplays() (Line: 1333) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54) Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228) Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 144) Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104) Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82) Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 1876) Drupal\views\ViewExecutable->buildTitle() (Line: 338) Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733) Drupal\views\ViewExecutable->attachDisplays() (Line: 1333) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54) Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228) Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 110) Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82) Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 1876) Drupal\views\ViewExecutable->buildTitle() (Line: 338) Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733) Drupal\views\ViewExecutable->attachDisplays() (Line: 1333) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 35) Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894) Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045) Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903) Drupal\views\ViewExecutable->initHandlers() (Line: 1876) Drupal\views\ViewExecutable->buildTitle() (Line: 338) Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733) Drupal\views\ViewExecutable->attachDisplays() (Line: 1333) Drupal\views\ViewExecutable->build() (Line: 392) Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196) Drupal\views\Plugin\views\display\Page->execute() (Line: 1635) Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81) Drupal\views\Element\View::preRenderViewElement(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '6e7ea336-e513-4349-a3ec-f7cc14d9cd1b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '6e7ea336-e513-4349-a3ec-f7cc14d9cd1b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '6e7ea336-e513-4349-a3ec-f7cc14d9cd1b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '6e7ea336-e513-4349-a3ec-f7cc14d9cd1b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '61138555-e1c0-45a5-9bbb-dcefc4489cf9') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '61138555-e1c0-45a5-9bbb-dcefc4489cf9') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '61138555-e1c0-45a5-9bbb-dcefc4489cf9') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '61138555-e1c0-45a5-9bbb-dcefc4489cf9') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c7517dfc-1136-438b-b5c4-736188acc9ea') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c7517dfc-1136-438b-b5c4-736188acc9ea') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c7517dfc-1136-438b-b5c4-736188acc9ea') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'c7517dfc-1136-438b-b5c4-736188acc9ea') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bd8c8912-3173-4504-886e-057331c10f2a') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bd8c8912-3173-4504-886e-057331c10f2a') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bd8c8912-3173-4504-886e-057331c10f2a') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bd8c8912-3173-4504-886e-057331c10f2a') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '98f6ede6-aae6-4e3b-89fa-9826e897310c') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '98f6ede6-aae6-4e3b-89fa-9826e897310c') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '98f6ede6-aae6-4e3b-89fa-9826e897310c') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '98f6ede6-aae6-4e3b-89fa-9826e897310c') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras: El objetivo es añadir a esta tabla una columna que indique el número de días transcurridos desde la compra anterior (anterior en el tiempo, pues nada nos asegura que el orden de los datos en la tabla original sea cronológico, y ya sabemos que Power BI tampoco asegura el orden de las filas). La resolución de este escenario no es sencilla. Aun cuando podría resolverse en una única expresión, se plantea a continuación su resolución paso a paso. Las fases involucradas son las siguientes: <ol><li>Es necesario obtener, para cada fecha de compra del cliente X, la fecha de la anterior compra.</li> <li>La anterior fecha de compra es la mayor fecha de todas las compras del cliente X (exceptuando la compra que estemos analizando, por supuesto).</li> <li>Podemos obtener todas las compras anteriores del cliente X realizando una combinación cruzada de la tabla consigo misma tomando como campo común el correspondiente al identificador del cliente y considerando en la tabla de la derecha (véase la documentación de la función <a href="/es/dax/function/generate">GENERATE</a>) solo las fechas anteriores a la de la fecha de compra siendo considerada en la tabla izquierda. Así, por ejemplo, para la compra que aparece en la tercera línea de la imagen anterior (correspondiente al cliente 1, con fecha de 21 de enero de 2019), una combinación cruzada con la misma tabla en las condiciones mencionadas devolvería una fila para la combinación de la fila 3 y la fila 1 (mismo cliente y fecha anterior) y otra para la combinación de la fila 3 y la fila 2 (de nuevo, mismo cliente y fecha anterior).</li> </ol>Por último, una vez obtenida la tabla mencionada en el punto 1, bastaría calcular la diferencia entre cada fecha de compra y la fecha de la última compra. Vamos punto por punto. En primer lugar queremos obtener, para cada fila (es decir, para cada compra), el conjunto de compras anteriores del mismo cliente. Esto, como se ha comentado, puede lograrse con una combinación cruzada que nos permita especificar las condiciones de la combinación, es decir, con la función <a href="/es/dax/function/generate">GENERATE</a>. Como esta función requiere que las tablas involucradas en la combinación tengan campos con nombres diferentes, vamos modificar los nombres de los campos de la segunda copia con la función <a href="/es/dax/function/selectcolumns">SELECTCOLUMNS</a>, añadiendo un símbolo "_" al final de los nombres: SelfJoin = GENERATE( Sales; FILTER( SELECTCOLUMNS( Sales; "Customer_"; Sales[Customer]; "Purchase Date_"; Sales[Purchase Date] ); [Purchase Date_] < Sales[Purchase Date] && Sales[Customer] = [Customer_] ) ) Tal y como se ve, estamos obteniendo la combinación cruzada imponiendo la condición de que el identificador de cliente sea el mismo, y que las fechas de la columna de la derecha sean inferiores a la fecha considerada en cada una de las filas de la izquierda (para simplificar, estamos suponiendo que un mismo cliente no va a realizar dos compras el mismo día). Obsérvese que no aparecen los registros de la primera tabla para los que no hay registros en la segunda que cumplan las condiciones impuestas (es decir, en la tabla que acabamos de crear, solo se incluyen fechas de compra para las que hay alguna compra anterior). Obtener, a partir de aquí, la fecha anterior a cada compra es fácil: basta con agrupar (con la función <a href="/es/dax/function/groupby">GROUPBY</a>) por cliente y fecha de compra (campos <em>Customer</em> y <em>Purchase Date</em>) y seleccionar el valor máximo (de cada grupo) del campo <em>Purchase Date_</em>: LastPurchases = GROUPBY( SelfJoin; SelfJoin[Customer]; SelfJoin[Purchase Date]; "Last Purchase"; MAXX( CURRENTGROUP(); SelfJoin[Purchase Date_] ) ) Ahora viene un proceso un tanto complicado: como en la tabla solo se incluyen fechas de compra para las que existe una compra anterior, para que en el resultado final aparezcan todas las fechas originales tendríamos que realizar una combinación externa izquierda entre la tabla de fechas original y la nueva. Para esto tendríamos que usar la función <a href="/es/dax/function/naturalleftouterjoin">NATURALLEFTOUTERJOIN</a>, pero esta función exige que las tablas a combinar tengan la misma ascendencia (procedan de la misma fuente), lo que no se cumple en nuestro caso. Tal y como se explica en la <a href="/es/dax/function/naturalleftouterjoin">documentación de esta función</a>, es posible resolver este problema añadiendo una cadena de texto vacía al final de los nombres: Purchase and Last Purchase = NATURALLEFTOUTERJOIN( SELECTCOLUMNS( Sales; "Customer"; Sales[Customer] & ""; "Purchase Date"; Sales[Purchase Date] & "" ); SELECTCOLUMNS( LastPurchases; "Customer"; LastPurchases[SelfJoin_Customer] & ""; "Purchase Date"; LastPurchases[SelfJoin_Purchase Date] & ""; "Last Purchase"; LastPurchases[Last Purchase] ) ) Por último, para calcular el número de días desde la última compra basta con añadir una nueva columna que devuelva la diferencia (solo si existe una última compra): Days since last purchase = ADDCOLUMNS( 'Purchase and Last Purchase'; "# days"; VAR NumberOfDays = 'Purchase and Last Purchase'[Purchase Date] - 'Purchase and Last Purchase'[Last Purchase] RETURN IF( ISBLANK('Purchase and Last Purchase'[Last Purchase]); BLANK(); NumberOfDays ) ) Para devolver la diferencia de días comentada utilizamos la función <a href="/es/dax/function/if">IF</a> para confirmar si el valor del campo correspondiente a la última compra es un BLANK o no, para lo que utilizamos la función <a href="/es/dax/function/isblank">ISBLANK</a>. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb9f4ae-e4af-4486-9175-e93ad731a82b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb9f4ae-e4af-4486-9175-e93ad731a82b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb9f4ae-e4af-4486-9175-e93ad731a82b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb9f4ae-e4af-4486-9175-e93ad731a82b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8bbd8758-9ff2-4813-90aa-fae48f39077d') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8bbd8758-9ff2-4813-90aa-fae48f39077d') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8bbd8758-9ff2-4813-90aa-fae48f39077d') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8bbd8758-9ff2-4813-90aa-fae48f39077d') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3aa1909-9a3f-40ee-876d-9106416dedb9') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3aa1909-9a3f-40ee-876d-9106416dedb9') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3aa1909-9a3f-40ee-876d-9106416dedb9') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f3aa1909-9a3f-40ee-876d-9106416dedb9') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de un listado de productos: ...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas: Como puede apreciarse, esta información está, en este caso, almacenada en ficheros Excel. Una vez importadas ambas tablas con los nombres de "Productos" y "Ventas" respectivamente, y una vez confirmado que se crea la relación entre ambas tomando el campo "Id Producto" como clave, querríamos añadir a la tabla de productos, una columna calculada con el valor máximo de unidades involucradas en las ventas de cada producto. Así, por ejemplo, en la imagen anterior vemos que el producto 3 ha sido vendido dos veces, la primera involucrando 6 unidades, y la segunda involucrando 11, por lo que querríamos obtener el número 11 como valor máximo encontrado. Para esto vamos a recorrer la tabla de productos buscando, para cada uno de ellos, el valor máximo en cuestión. En pseudo-código sería lo siguiente: Para cada uno de los productos: = Obtén la lista de ventas de dicho producto y quédate con el valor máximo del campo "Unidades" Si conseguimos obtener la lista de ventas de cada producto, la función que nos permitiría recorrer dicha lista y extraer un valor máximo es <a href="/dax/function/maxx">MAXX</a>. Esta función permite especificar una tabla (la de ventas de cada producto en nuestro caso) y una expresión que se evaluará para todas las filas de la misma (simplemente el número de unidades involucradas en nuestro ejemplo), devolviéndose el valor máximo encontrado. Ahora, para cada fila recorrida el pseudo-código sería el siguiente: = MAXX( Lista de ventas del producto considerado en la fila; // Obtiene el valor máximo de esta tabla... Unidades // Según este criterio ) La obtención de la lista de ventas asociada a cada producto también es sencilla: estamos recorriendo la tabla de productos, por lo que, para cada uno de ellos, el campo "Id Producto" nos permitiría filtrar la tabla de ventas adecuadamente usando la función <a href="/dax/function/filter">FILTER</a>. En nuestro caso, la expresión a usar sería la siguiente: FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]) Estaríamos filtrando la tabla "Ventas" para incluir solo las ventas asociadas al producto "Id Producto". El código final sería el siguiente: Max Unidades Vendidas = MAXX( FILTER(Ventas; Ventas[Id Producto] = Productos[Id Producto]); Ventas[Unidades] ) Y el resultado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '4d15db25-b820-4d55-a64a-11e6c7873911') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '4d15db25-b820-4d55-a64a-11e6c7873911') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '4d15db25-b820-4d55-a64a-11e6c7873911') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '4d15db25-b820-4d55-a64a-11e6c7873911') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd95f7abc-caec-4c13-a131-40b2d7adf918') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd95f7abc-caec-4c13-a131-40b2d7adf918') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd95f7abc-caec-4c13-a131-40b2d7adf918') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd95f7abc-caec-4c13-a131-40b2d7adf918') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3ec18874-8211-46d1-a026-3ad2abd9e35a') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3ec18874-8211-46d1-a026-3ad2abd9e35a') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3ec18874-8211-46d1-a026-3ad2abd9e35a') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3ec18874-8211-46d1-a026-3ad2abd9e35a') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '91de6bd0-e7e0-403e-8b7b-6fe56db90e0d') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '91de6bd0-e7e0-403e-8b7b-6fe56db90e0d') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '91de6bd0-e7e0-403e-8b7b-6fe56db90e0d') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '91de6bd0-e7e0-403e-8b7b-6fe56db90e0d') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es <em>'Product'[ProductName]</em> y la medida <em>[Total sales]</em> suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida: max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) Básicamente estamos extrayendo los nombres de los productos con la función <a href="/dax/function/values">VALUES</a>, calculando las ventas totales para cada uno de ellos y quedándonos con el mayor valor utilizando la función <a href="/dax/function/maxx">MAXX</a>: Sin embargo, extraer el nombre del producto correspondiente a dicha cifra no es tan sencillo. Una estrategia -una vez que sabemos cuál es su cifra de ventas- sería recorrer la lista de nombres de productos, calcular su cifra de ventas, compararla con el valor máximo ya conocido y devolver el nombre si la cifra calculada coincide. En pseudo-código, sería algo así: max_sales = valor de ventas para el producto más vendido Para cada nombre de producto: sales = valor de ventas si sales = max_sales: return nombre de producto Una forma de devolver solo el nombre de producto de interés es recorrer el listado de nombres de producto, comparar su cifra de ventas con la cifra máxima ya calculada y devolviendo un valor no vacío si coinciden y un <a href="/dax/function/blank">BLANK()</a> si no coinciden, y usar a continuación la función iteractiva <a href="/dax/function/firstnonblank">FIRSTNONBLANK</a> que extrae el nombre del producto correspondiente al primer (y único en este ejemplo) valor no vacío. En pseudo-código sería: max_sales = valor de ventas para el producto más vendido return FIRSTNONBLANK( Para cada nombre de producto sales = valor de ventas si sales = max_sales: return cualquier valor no vacío else: return BLANK() ) Es decir, podemos verlo como si estuviésemos generando una tabla temporal de una única columna en la que todos los valores serían blank salvo el correspondiente al producto para el que se cumpliese la condición sales = max_sales (es decir, al producto más vendido). El código anterior en DAX quedaría de la siguiente forma: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN FIRSTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) Comenzamos calculando el valor máximo de ventas (<em>max_sales</em>) y devolviendo el nombre del producto correspondiente al primer (y único) valor no vacío de una imaginaria tabla intermedia, tabla que creamos a partir de la columna conteniendo los nombres de los productos en la que "sustituímos" el nombre del producto más vendido por un 1 (podría ser cualquier otro valor) y el resto de nombres de productos por un blank utilizando la función <a href="/dax/function/if">IF</a>: Para confirmar que el resultado es correcto podemos crear una visualización con la lista de productos y sus ventas totales, y ordenar dicha tabla según la cifra de ventas: Como la "tabla temporal" solo contiene un único valor no vacío, también podríamos haber utilizado la función <a href="/dax/function/lastnonblank">LASTNONBLANK</a>: Max sales product = VAR max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales]) RETURN LASTNONBLANK( 'Product'[ProductName]; IF( [Total sales] = max_sales ; 1; BLANK() ) ) ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '96494bcb-fe75-421b-8f87-db56ee6f1d2b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '96494bcb-fe75-421b-8f87-db56ee6f1d2b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '96494bcb-fe75-421b-8f87-db56ee6f1d2b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '96494bcb-fe75-421b-8f87-db56ee6f1d2b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'df216c47-c8c0-41eb-ab0a-991917599a9d') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'df216c47-c8c0-41eb-ab0a-991917599a9d') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'df216c47-c8c0-41eb-ab0a-991917599a9d') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'df216c47-c8c0-41eb-ab0a-991917599a9d') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3acd4fe9-c39b-4752-8526-ede313a7b2a0') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3acd4fe9-c39b-4752-8526-ede313a7b2a0') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3acd4fe9-c39b-4752-8526-ede313a7b2a0') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3acd4fe9-c39b-4752-8526-ede313a7b2a0') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7b547472-d0c6-41d8-8711-3a5192760aee') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7b547472-d0c6-41d8-8711-3a5192760aee') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7b547472-d0c6-41d8-8711-3a5192760aee') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7b547472-d0c6-41d8-8711-3a5192760aee') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '390dbbbf-8984-403f-8733-8d3ee69b5dc7') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '390dbbbf-8984-403f-8733-8d3ee69b5dc7') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '390dbbbf-8984-403f-8733-8d3ee69b5dc7') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '390dbbbf-8984-403f-8733-8d3ee69b5dc7') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '79fc6517-49bf-471c-b440-a221ce20a369') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '79fc6517-49bf-471c-b440-a221ce20a369') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '79fc6517-49bf-471c-b440-a221ce20a369') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '79fc6517-49bf-471c-b440-a221ce20a369') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'ed2d8e78-9985-4165-8118-f0824d06bd9b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'ed2d8e78-9985-4165-8118-f0824d06bd9b') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'ed2d8e78-9985-4165-8118-f0824d06bd9b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'ed2d8e78-9985-4165-8118-f0824d06bd9b') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd918aa2a-faf7-41b9-9eab-c48896db8378') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd918aa2a-faf7-41b9-9eab-c48896db8378') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd918aa2a-faf7-41b9-9eab-c48896db8378') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd918aa2a-faf7-41b9-9eab-c48896db8378') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría: 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). La resolución de este escenario incluye dos pasos: 1. En el primero deberemos calcular el valor máximo de cada categoría para llegar a una tabla intermedia semejante a la siguiente: 2. En el segundo deberemos recorrer la tabla intermedia generada sumando los valores encontrados. 1er paso 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: SUMMARIZE El código sería el siguiente: Max value per category summarize = SUMMARIZE( Data; Data[Category]; "Max value"; MAX(Data[Value]) ) 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: SUMMARIZECOLUMNS En este segundo caso el código sería el siguiente: Max value per category summarizecolumns = SUMMARIZECOLUMNS( Data[Category]; "Max value"; MAX(Data[Value]) ) 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>. GROUPBY Por último, utilizando la función <em>GROUPBY </em>el código quedaría de la siguiente forma: Max value per category groupby = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) 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>. 2º paso 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: SUMMARIZE El código para esta primera función sería el siguiente: Sum of max value per category = SUMMARIZE( 'Max value per category groupby'; "Max"; SUM('Max value per category groupby'[Max value]) ) 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: Al no haber especificado el campo de agregación, DAX agrega todos los valores numéricos. 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") SUMMARIZECOLUMNS Con esta función, el código sería el siguiente: Sum of max value per category = SUMMARIZECOLUMNS( "Max"; SUM('Max value per category groupby'[Max value]) ) 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: 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. GROUPBY En este último caso, el código sería el siguiente: Sum of max value per category = VAR Max_value_per_category = GROUPBY( Data; Data[Category]; "Max value"; MAXX(CURRENTGROUP(); Data[Value]) ) RETURN GROUPBY( Max_value_per_category; "Sum"; SUMX(CURRENTGROUP(); [Max value]) ) 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: 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. ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2b6e74a4-1aaa-4448-b6f3-018249d85a2e') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2b6e74a4-1aaa-4448-b6f3-018249d85a2e') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2b6e74a4-1aaa-4448-b6f3-018249d85a2e') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2b6e74a4-1aaa-4448-b6f3-018249d85a2e') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '28eeb081-03c0-4a9e-a2ca-62575e0c2f0f') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '28eeb081-03c0-4a9e-a2ca-62575e0c2f0f') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '28eeb081-03c0-4a9e-a2ca-62575e0c2f0f') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '28eeb081-03c0-4a9e-a2ca-62575e0c2f0f') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'a078d921-b097-4d8d-b0ad-cc0336356343') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'a078d921-b097-4d8d-b0ad-cc0336356343') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'a078d921-b097-4d8d-b0ad-cc0336356343') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'a078d921-b097-4d8d-b0ad-cc0336356343') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '16b99db9-6e42-49ab-a76c-4b16388c1658') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '16b99db9-6e42-49ab-a76c-4b16388c1658') (Line: 95) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '16b99db9-6e42-49ab-a76c-4b16388c1658') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147) Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80) Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640) Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63) Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '16b99db9-6e42-49ab-a76c-4b16388c1658') (Line: 124) Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores. Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (<em>Product[ProductName]</em>) a filas y el campo conteniendo los países (<em>Geography[Country]</em>) a columnas: Comprobamos cómo, por ejemplo, el valor máximo de ventas para el producto "<em>All-Purpose Bike Stand</em>" (el primero de la lista) es de 13.515€ -cifra correspondiente a los Estados Unidos-. Lo que deseamos, por lo tanto, es un listado de los productos acompañado, cada uno de ellos, por el valor máximo de sus ventas en el país que sea. La función <a href="/dax/function/maxx">MAXX </a>recorre una tabla evaluando, para cada fila, una expresión y escogiendo el valor máximo de los resultados obtenidos. En nuestro caso, para cada producto, querríamos recorrer una tabla de países evaluando las ventas totales del producto del que se trate en cada país. Algo como: MAXX(<listado-de-países>; <ventas>) El listado de países lo podemos obtener a partir del campo que contiene los países en los que se realizan las ventas utilizando la función <a href="/dax/function/values">VALUES </a>que extrae los valores del mismo: VALUES(Geography[Country] Por último, si tenemos una medida <em>Sales</em> que sume el campo de ventas, podríamos obtener el resultado buscado con la medida: Product max sales = MAXX(VALUES(Geography[Country]); [Sales]) En esta expresión, recorremos una tabla creada dinámicamente conteniendo el listado de países (<em>VALUES(Geography[Country])</em>) evaluando, para cada fila, la expresión <em>[Sales]</em>. Esta medida se contextualiza para cada fila devolviendo solo las ventas de cada país. El resultado, si lo llevásemos a una tabla, sería: La medida <em>Product max sales</em>, si la llevásemos directamente a una visualización tipo <em>tarjeta</em>, mostraría el valor máximo de este listado de ventas: Ahora bien, cuando llevemos esta medida a una tabla, también va a contextualizarse. Por ejemplo, si en dicha tabla tenemos un listado de productos, la tabla de países creada dinámicamente incluirá solo las ventas por país para dicho producto, y el valor máximo calculado por MAXX será el correspondiente solo a dicho producto. Por lo tanto, basta crear una tabla con el listado de productos y esta medida para obtener el resultado deseado: ', 'es') (Line: 118) Drupal\filter\Element\ProcessedText::preRenderText(Array) call_user_func_array(Array, Array) (Line: 101) Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788) Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88) __TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 46) __TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array, Array) (Line: 43) __TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74) __TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array) (Line: 479) Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110) __TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405) Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378) Twig\Template->display(Array) (Line: 390) Twig\Template->render(Array) (Line: 55) twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384) Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433) Drupal\Core\Render\Renderer->doRender(Array) (Line: 446) Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204) Drupal\Core\Render\Renderer->render(Array, ) (Line: 242) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
include('/var/www/vhosts/interactivechaos.ovh/httpdocs/modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php') (Line: 578) Composer\Autoload\ClassLoader::Composer\Autoload\{closure}('/var/www/vhosts/interactivechaos.ovh/httpdocs/modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php') (Line: 432) Composer\Autoload\ClassLoader->loadClass('Drupal\google_analytics\Component\Render\GoogleAnalyticsJavaScriptSnippet') (Line: 372) google_analytics_page_attachments(Array) (Line: 313) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'google_analytics') (Line: 405) Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_attachments', Object) (Line: 310) Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 288) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Drupal\user\Entity\Role::postLoad(Object, Array) (Line: 423) Drupal\Core\Entity\EntityStorageBase->postLoad(Array) (Line: 353) Drupal\Core\Entity\EntityStorageBase->loadMultiple() (Line: 126) eu_cookie_compliance_page_attachments(Array) (Line: 313) Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'eu_cookie_compliance') (Line: 405) Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_attachments', Object) (Line: 310) Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 288) Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132) Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90) Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) call_user_func(Array, Object, 'kernel.view', Object) (Line: 142) Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191) Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128) Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Partimos de un listado de ventas (Sales) en el que se indica -por ejemplo- el identificador de cliente y las fechas de las compras:
En este escenario partimos de un listado de productos:
...y de un listado de ventas de estos productos, incluyendo el número de unidades de cada uno involucrados en las ventas:
Calcular el importe total de ventas para el producto más vendido es relativamente fácil. Si el campo que contiene los nombres de los productos es 'Product'[ProductName] y la medida [Total sales] suma el campo correspondiente al importe de ventas, bastaría con crear la siguiente medida:
max_sales = MAXX(VALUES('Product'[ProductName]); [Total sales])
En este escenario partimos de una tabla de hechos ("Data") en la que cada registro tiene asignado una categoría:
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).
La resolución de este escenario incluye dos pasos:
En este escenario tenemos un conjunto de productos, las ventas y un listado de países en los que se han realizado las ventas. Y queremos calcular, para cada producto, las ventas del país en el que éstas hayan sido mayores.
Comencemos viendo las ventas por país. Para esto llevamos a una matriz el campo conteniendo el nombre de cada producto (Product[ProductName]) a filas y el campo conteniendo los países (Geography[Country]) a columnas:
Excepto donde se indique otra cosa, los contenidos de este sitio web se ofrecen bajo una licencia Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional