美文网首页PowerBICALCULATE
CALCULATE 庖丁解牛系列- 扩展表 (4)

CALCULATE 庖丁解牛系列- 扩展表 (4)

作者: PowerBI非官方 | 来源:发表于2018-07-04 18:24 被阅读69次

    筛选与扩展表

    (来自官方简体笔记)

        DAX里的筛选表

          本文介绍了一些可用于在DAX中筛选表的技术, 显示了在你了解它们后可以避免的可能的错误行为及缺陷, 特别是当使用双向筛选器时。

            在学习 DAX 时, 最难做的事情之一就是需要摆脱常识性的推理, 学习遵循一组新的规则: 它们是在逻辑语境中定义的、并且有些独特的思维。如果你之前有一定的编程或查询基础, 你将倾向于将以前的知识映射到 DAX, 而忘记遵循使用该语言的基本规则的简单思维路径。

          在开始时,我想举几个例来充当思维陷阱(坑)。所有这些示例都是如何筛选表的基本变体。这些计算的数字本身没有意义。我们的目标就是用它们理解这个理论。把它映射到真实的例子是留给读者的一个有趣的练习。
          让我们从以下代码开始,它返回所有行的相同值:

    DEFINE
    MEASURE Sales[Test]=
    CALCULATE (SUM ( Sales[Quantity]),
    ALL( 'Product' ) )
    EVALUATE
    ADDCOLUMNS ( VALUES ( 'Product'[Color] ), "Test",[Test] )

    其结果是:

    按此模式再举一例:

    接着解释前面的公式返回所有行的相同值的原因是:

          ADDCOLUMNS在Product[Color]列上创建了一个行筛选,但是该度量包含了ALL ( 'Product' ),它消除了由筛选转换生成的筛选器的影响。通过在Sales-销售表(事实表)上,而不是产品表上执行ALL()操作,你可以获得类似的效果。事实上,如果你定义以下度量:

    DEFINE
    MEASURE Sales[Test] =
    CALCULATE(SUM( Sales[Quantity] ),
    ALL( 'Product'[ProductKey] ))
    EVALUATE
    ADDCOLUMNS( VALUES ( 'Product'[Color] ),
    "Test",[Test] )

          结果是:同样的值重复出现在所有行中。虽然这是需要的正确值, 但很多人并不真正能理解为什么会发生这种情况。事实上, 在考虑如何在 DAX 中使用Product[Color]列筛选Sales-销售表时,这是一个普遍的想法:

        (1)ADDCOLUMNS 通过 " Color" 列筛选Product表。
        (2)Product[Color]上的筛选器依据Product [ProductKey] 列的一组值提供筛选。

          上述Product[ProductKey]列的子集将成为Sales [ProductKey]上的筛选器, 并将此筛选应用于Sales-销售表, 结果只对给定的Color-颜色进行销售计算。换句话说,Product[Color]上的筛选器将成为Sales[ProductKey] 的筛选器。不幸的是,这是不正确的。如果后者是真的, 则下面的代码将返回所有行的相同值, 而实际上每一行都返回了不同的值:

    DEFINE
    MEASURE Sales[Test] =
    CALCULATE(SUM( Sales[Quantity] ),ALL( Sales[ProductKey] ) )
    EVALUATE
    ADDCOLUMNS(VALUES( 'Product'[Color] ),
    "Test",[Test] )

      结果为:

          这里,通过使用  ALL( Sales[ProductKey] ),你清除了Sales[ProductKey]列上的任何筛选器,但是color-颜色列的筛选器仍然有效。这种行为的原因非常简单:筛选器从来没有被放在Sales[ProductKey]列上,该筛选器只针对Product [Color]列。
          如果你认为—就像你在关系数据库中所做的那样:筛选器通过把两个表连接在一起来工作,那么,你就错了。进一步的测试,如果你仍然不相信我,你可以再尝试以下的DAX

    DEFINE
    MEASURE Sales[Test] =
    CALCULATE(
    SUM ( Sales[Quantity] ), ALL( 'Product'[ProductKey]) )

    EVALUATE
    ADDCOLUMNS ( VALUES ( 'Product'[Color] ),
    "Test",[Test] )

          同样,结果对于每一行都有不同的值。即使你从Product[ProductKey]中移除筛选器,Product[Color]列的筛选器仍然保持不变。关键是:这种行为与筛选的工作方式没有任何联系。筛选器只能通过使用扩展表来定义(在本系列的其他文章里,你了解更多关于扩展表的知识)。

          扩展版的Sales表包含Product列。因此,当筛选Product[Color]时,它将同时筛选Sales表,而无需考虑关系、字段键或任何其他“关系”工具。因为扩展模型(Sales表)包含Product[Color]列,所以,可以通过筛选Product[Color]来筛选Sales销售表。
            那么,为什么这个方法可以去掉筛选器呢?

    DEFINE
    MEASURE Sales[Test] =
    CALCULATE(
    SUM ( Sales[Quantity] ),ALL ( Sales ))

    EVALUATE
    ADDCOLUMNS ( VALUES ( 'Product'[Color] ),
    "Test",[Test] )

          原因是, 此代码清除了Product[Color]上的筛选器。因为ALL ( Sales ) 删除了扩展Sales表中的任何列上的任何筛选器。请记住:

          在 DAX 中, 当你引用一个筛选器参数中的表时,这样的表总是被扩展。

            因此,ALL( Sales ) 参数不仅从Sales的任何原列表中移除筛选器(正如我们所看到的那样,在这种情况下不会产生任何效果),但它也从Sales的关系列中移除筛选器,其中当然也包括Product[Color]。
            如果你还需要说服自己,你可以使用Sales表的所有列, 这时会注意到Product[Color]上的筛选器仍然在那里。删除它的唯一方法是:

            筛选Product表或使用扩展的Sales表。

            当激活AnalysisServices 2016或PowerBI 中的双向筛选时, 该方案变得更加复杂。事实上,双向筛选并不适用于表的扩展。相反,双向筛选是通过在执行查询时以显式方式加入事实表筛选器来执行的。这就造成了在使用该筛选器时需要额外的注意。

        双向筛选与扩展表

          请考虑以下模型,通过使用中间维度表(Accounts)和(AccountCustomer)桥接表将客户链接到Transactions-交易记录表。为了使该多到多的关系工作,我们启用了AccountCustomer桥接表和Account表之间的双向筛选关系。

          一个简单的报告,显示生成CustomerName的金额总和,遍历到多到多的关系, 并生成一个类似以下的正确结果:

            有必要回顾一下这里所发生的事情。
            Customer客户正在筛选bridge桥表, 而桥接表则通过双向关系筛选到Account帐户表。作为最后一步, Account表将筛选事务记录表--Transactions。让我们更准确地说说扩展表的几个方面:
          (1)AccountCustomer 扩展到Customer表。因此, Customer表上的筛选器也会筛选桥表bridge。

          (2)Transactions事务表扩展到Account,因此, Account表上的筛选也会对事务进行筛选。
          (3)AccountCustomer表扩展到Account表, 但为了激活这种筛选,我们需要在计算中使用 AccountCustomer表作为一个筛选器参数。使用双向筛选器获得了这种效果。

          在这里, 重要的部分是了解这个筛选器不是通过扩展表来移动的,而是通过加入筛选器实现的。你可以通过使用"桥接表" 的老方法将筛选器从多端移动到一端来获得类似的行为, 如下面的代码所示:

    CALCULATE( [SumOfAmount],AcccountCustomer )
    其中,SumOfAmount(元度量)的简单定义为:
    SumOfAmount:=SUM(Transactions[Amount] )

          为什么说到筛选器,它们是相关连的?因为在这种情况下: 双向筛选器引入的筛选器不能简单地使用事实数据表中的ALL()来删除。
          实际上,如果你编写了一个新的度量值, 用于从事务表中移除筛选器, 从而包含其扩展表 (包括Accounts帐户), 则结果不是所期望的。请考虑以下公式:

    SumOfAllAmount =
    CALCULATE( [SumOfAmount],ALL( Transactions ) )

          它产生的结果与所之前度量的结果完全相同:

          这里,从Transactions交易记录表和Account帐户表中正确地删除了筛选器 (Account包含在扩展表的交易记录中)。但是, 桥接表上的筛选器是通过在扩展表之外工作的机制,这里是在Accounts表上运行的。因此, 要从事实数据表中删除该筛选器, 当它来自bridge桥接表维度时, 也需要从 bridge 表中删除该筛选器。

          实际上,下面的代码会执行正确删除筛选器:

    SumOfAllAmount :=
    CALCULATE (
    [SumOfAmount],ALL( AccountCustomer ) )

    下图显示了该公式的正确结果(总是一个绝对值):

          不需要从事实数据表或维度表中删除筛选器, 因为它们的筛选器确实来自于桥表 (实际上,从Account表直接和桥表间接地连接方式)。在本例中, 从Account表或事务表中移除筛选器, 证明是无用的。
          正如你所看到的,乍一看, 这与 DAX 处理筛选器似乎不一致, 但这只有当你不考虑扩展表的情况下是正确的。整个 DAX 关系模型是基于扩展表的, 当你掌握了以上概念后, 一切突然变得更有意义了。

    未完待续


    相关文章

      网友评论

        本文标题:CALCULATE 庖丁解牛系列- 扩展表 (4)

        本文链接:https://www.haomeiwen.com/subject/qskyuftx.html