对编写DAX查询非常有用的三个“集合函数”
本文介绍了操作集合的DAX函数的功能,它们对于创建查询很有用,有时还有助于制定度量。在本文中,我们将“集合函数”称为对集合进行操作的函数。DAX中可用的三个设置函数是:UNION,INTERSECT和EXCEPT。它们的功能非常直观:
-
UNION执行两个或更多表的联合。
-
INTERSECT执行两个表之间的相交设置。
-
EXCEPT从第一个参数中删除第二个参数的行。
这些函数将两个或多个表作为参数并返回一个表。它们不仅对编写DAX查询非常有用,而且开发人员在实施措施时也可以使用这些功能来准备复杂的过滤器。
set函数最常使用的功能是保持数据沿袭,这在准备过滤器时至关重要。如果沿袭丢失,则可以使用TREATAS恢复沿袭或强制重新传承。
我们从设置函数的基础开始,然后是关于数据沿袭的见解。
UNION
UNION接受两个或多个表,并返回一个表,其中所有表的所有行均作为参数接收。结果的结构与源表的结构相同,并且保留重复(如果存在)。如果需要删除重复项,则可以在UNION上使用DISTINCT。
为了使用UNION来实现示例,我们使用两个变量表。每个表都包含一个带有“星期几”列的表格,每一行代表一个工作日。从周日开始,我们对工作日进行编号。因此,1代表星期日,2代表星期一,7代表星期六。
用Dax表达式创建新表,操作如下图;
用Dax表达式创建MonTue表,用以下Dax表达式如下:
这些变量每个都包含两行。在下面的示例中,我们在两个表上使用UNION。结果是一个包含源表的所有行的表,包括重复项:
以上结果如我们所见,包含两个表中的所有行,星期一的重复行不会被删除。
DISTINCT
DISTINCT被证明对删除重复项很有用,如下:
INTERSECT
INTERSECT接受两个表作为参数。它返回第一个参数中也存在于第二个参数中的所有行,并且保留第一个参数中存在的所有重复项。参数的顺序很重要:只有在第一个参数中存在重复项时,才保留重复项。
在以下示例中,我们在前面示例中使用的一周的同一天的临时表上使用INTERSECT。结果仅包含星期一,因为这是两个表之间唯一的共同工作日:
为了测试重复项,我们添加了SunMonMonWed变量,该变量包含SunMon和MonWed的并集。该表包含星期一两次;因此,它拥有一个副本:
在下面的示例中,我们在SunMonMonWed上使用INTERSECT作为第一个参数,在MonTue上使用第二个参数。结果仅包含星期一,但是重复;的确MonTue包含星期一,没有在其他日期SunMonMonWed。
更改参数的顺序会更改结果。因为星期一仅在MonTue变量中出现一次(我们现在将其用作第一个参数),所以结果仅包含星期一一次。
EXCEPT
设置功能的第三个也是最后一个是EXCEPT。除接受两个表作为参数外,它返回表1中不存在于表2中的所有行。使用EXCEPT时,参数的顺序至关重要。确实,EXCEPT仅在第一个参数中出现时才保留重复项。
作为第一个示例,我们将EXCEPT与SunMon作为第一个参数,将MonTue作为第二个参数。结果是一个只有星期日的表,因为第二个参数中存在星期一,并将其从结果中删除:
在下一个示例中,我们更改参数的顺序。我们将EXCEPT与MonTue作为第一个参数,将SunMon作为第二个参数。结果仅包含星期二,因为它是第二个参数中不存在的唯一工作日。
具有不同列名和数据沿袭的表
set函数的参数可能具有不同的列名和不同的数据沿袭。这些函数按其位置将表格中的列匹配。当同一位置的列名称不同时,结果将使用第一个表中的名称。
关于数据沿袭,其行为取决于set函数:当自变量的数据沿袭不同时,UNION丢失数据沿袭,而INTERSECT和EXCEPT都保留其第一个自变量的沿袭。
我们将通过一些示例看到UNION在实践中的一些行为。
第一个示例显示UNION与不同的列名一起使用。下面的代码在三个不同的表上使用UNION,其中一列在每个表中具有不同的名称。结果使用第一个表中的列名:
第二个示例显示了在具有相同数据沿袭的两个表上使用UNION时,数据沿袭得以保留。为此,我们在第一个代码示例中添加了度量评估。根据“星期几”列,结果每一行包含一个不同的值:
以上结果,由于两个表的数据沿袭都在同一“日期” [星期几]列中,因此UNION保留数据沿袭。星期一出现两次,因为UNION不会删除重复项。
在下一个示例中,当对具有不同数据沿袭的表使用UNION时,数据沿袭将丢失。我们更换MonTue与MyMonTue包含相同的日子,但没有数据沿袭。由于UNION的两个自变量具有不同的数据沿袭,因此结果将丢失数据沿袭。此外,度量的评估为所有行产生相同的数字;
如果需要,我们可以使用TREATAS恢复数据沿袭。为了证明这一点,我们创建了MyMonTueDataLineage变量,该变量使用TREATAS恢复数据沿袭。现在,由于恢复了数据沿袭,因此结果是一周中每一天的销售额:
列数不同的表
set函数均不接受具有不同列数的参数。
在以下示例中,我们在SunMon(两列)和MonTue(一列)上使用EXCEPT。结果是一个错误:
具有不同列类型的表
如果set函数的参数具有相同的列数,但对应的列具有不同的数据类型,会发生什么情况?在这种情况下,UNION的行为不同于INTERSECT和EXCEPT。实际上,UNION将列类型从数字转换为字符串,而INTERSECT和EXCEPT则不进行任何转换,而是返回错误。另一方面,数字类型之间的转换适用于所有设置的函数。
在下面的示例中,我们创建两个表,T1,其中STRING和INTEGER类型的两列,T2,具有相反的配置。然后,我们应用UNION,该表返回包含两列的表,这两列均为STRING类型;
带有INTERSECT或EXCEPT的相同示例返回错误:
最后一个示例显示了使用INTERSECT在两个不同数值类型之间的有效转换。返回的表包含1,这是T1和T2之间的交集:
结论
集合函数的优点在于它们易于使用,并且通常可以完全按我们期望的那样工作。使用设置函数时最相关的主题是数据沿袭。通过遵循本文概述的规则,我们就可以轻松预测数据沿袭是保留还是丢失。万一丢失,可以使用TREATAS进行恢复。
推荐阅读
Power BI + Azure Synapse,打造出色分析体验!
技术交流
1.Power BI免费下载:http://www.yeacer.com/
Microsoft Power BI Desktop中文最新版:下载地址
2.欢迎加入的Power BI技术群,目前正在学习阶段,有兴趣的朋友可以一起学习讨论。
Power Data技术交流群:702966126 (验证注明:博客园Power BI)
更多精彩内容请关注微信公众号:悦策PowerBI
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载。