由于每种产品的只有1行,因此求产品明细表的行数(除标题行外)就相当于求各种产品的数量,新建一个矩阵图表,将产品名称和该度量值拖曳入矩阵表,如下图所示:

在这里插入图片描述
以CALCULATE函数的角度来看,这里外部上下文就是表格每行的行标签,即产品名称,每个产品名称在产品表中对应的只有一行数据,所以全部返回值都是1。

以下是具体的CALCULATE计算示例:

  1. 筛选条件为空,不影响外部上下文
    用CALCULATE函数新建一个度量值:
    产品数量1 = CALCULATE([产品数量]) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
该度量值因为没有内部筛选,所以完全依赖外部上下文,运行结果也和原度量值一致。
  • 添加限制条件,缩小上下文
    新建一个度量值“产品数量2”,限制计算时的产品类别:
    产品数量2 = CALCULATE([产品数量],'产品明细'[产品类别]="数码产品") 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
    将该度量值拖拽到上述的矩阵图表中,发现只有类别为“数码产品”的产品计数正常显示,而其他产品的数据没有显示。
    这是因为CALCULATE的第二个参数的限制,只筛选类别为“数码产品”的产品,限制了外部的上下文,非数码产品的产品都不再运算。
    在这里插入图片描述
    3.结合ALL函数,扩大上下文
    新建度量值“产品数量3”,筛选条件使用ALL函数:
    产品数量3 = CALCULATE([产品数量],ALL('产品明细')) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
    在这里插入图片描述
    这里筛选条件使用了ALL函数,ALL('产品表')表示清除产品表里的所有外部上下文,外部筛选器不起作用了,每行统计的都是该产品表中的所有产品的行数,因此每行的数据都是13。
    ALL函数可以用于计算每个产品的数量占总产品数量的比例:
    产品占比=DIVIDE([产品数量],[产品数量3]) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
    在这里插入图片描述
    4.重置上下文
    新建度量值“产品数量4”:
    产品数量4 = CALCULATE([产品数量],ALL('产品明细'),'产品明细'[产品类别]="数码产品") 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
    这里用ALL函数清除行标签的外部筛选后,从全部产品中统计品类为“数码产品”的产品的数量,所以每行都返回5。
    在这里插入图片描述
  • 3.2.4 常用的DAX函数

    3.2.4.1 FILTER函数

    FILTER函数用于筛选,参与CALCULATE函数第二个及之后的参数计算。

    FILTER函数的语法如下:

    FILTER(表,筛选条件)
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    其中,
    第一个参数:一定是表,是不能放入列或者值的;
    第二个参数:筛选条件。如果是多条件筛选,可以用&&符号或者||符号连接起来。
    返回值:一个表。不能直接用于建立度量值,但可以新建表,最常用的就是作为CALCULATE的参数,返回表中符合筛选条件的行,接着交给CALCULATE的第一个参数执行聚合运算。

    3.2.4.2 ALL函数

    ALL函数的参数可以是一个表,也可以是一个或多个列,但它返回的数据类型都是表。其用法如下:

    1.可单独用于创建表,参数为一个表,相当于复制表

    2.可单独用于创建表,参数为一列,返回该列的不重复列表

    3.可作为度量值中的参数,清除外部上下文

    3.2.4.3 VALUES函数

    VALUES函数的参数只有一个,即表的一列,但返回的数据类型是表,为该列的不重复值的列表,其语法如下:

    VALUES([]) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    注:如果某函数需要的参数是表,但想提供的是列,可以使用VALUES函数转换一下。

    VALUES函数的用法如下:
    1.返回某列的不重复列表,常用于通过事实表构建维度表(与ALL函数参数为一列时的功能相同)

    2.保持外部上下文筛选(该功能正好与ALL函数清除外部上下文功能相反)
    如3.2.3.4节中的度量值“产品数量4”利用ALL函数重置上下文,所有行返回了数码产品的数量5,如果想保持上下文的筛选,除了修改ALL函数之外,还可以加个VALUES函数:

    产品数量4 VALUES =  
    CALCULATE( 
    [产品数量], 
        ALL('产品明细'), 
        '产品明细'[产品类别]="数码产品", 
        VALUES('产品明细'[产品名称]) 
    )
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    将该度量值拖拽至矩阵图表中,如下图所示:
    在这里插入图片描述
    可以看到在CALCULATE函数内部添加了VALUES('产品名称'[产品名称])以后,计算结果又恢复了产品名称的筛选。

    3.查找文本型的数据
    如从产品明细表中找出零售价为199元的产品名称是什么,新建度量值如下:

    VALUES应用 查找文本 =  
    CALCULATE(VALUES('产品明细'[产品名称]),'产品明细'[零售价]=199) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    使用卡片来表示查找到的结果:
    在这里插入图片描述
    DAX有一个重要的特征:如果一个表只有一行一列,它同时也可以作为值使用。因此此处VALUES函数返回的是一个只有一行一列的表,在卡片中显示为一个查找结果值。

    3.2.4.4 HASONEVALUE函数

    HASONEVALUE(has one value)函数的英文意思是“有一个值”,它的参数为表的列,语法如下:

    HASONEVALUE([]) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    HASONEVALUE函数判断某列是否被过滤为仅有一个值,如果是一个值,返回TRUE;如果没有值或者有多个值,则返回FALSE。

    HASONEVALUE函数一般作为IF函数的第一个参数使用,判断交叉筛选后是否为一个值。

    例如,新建一个度量值,如果产品名称被筛选后只有一个值,返回这个产品名称,否则返回空值:

    IF ( HASONEVALUE ('产品明细'[产品名称]),VALUES ('产品明细' [产品名称] ) ) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    注:IF函数的第三个参数可以省略,如果省略,当第一个参数,也就是判断条件为FALSE时,默认返回BLANK()。

    又如,3.2.4.3节中使用VALUES函数筛选出产品明细表中零售价为199元的产品名称:

    VALUES应用 查找文本 =  
    CALCULATE(VALUES('产品明细'[产品名称]),'产品明细'[零售价]=199) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    如果产品明细表中零售价为199的产品不止一个,那么上述度量值将会发生错误。
    在这里插入图片描述

    为了防止错误的情况发生,可以利用IF和HASONEVALUE函数进行错误拦截,新建一个度量值:

    HASONEVALUE应用 =  
    IF( 
        HASONEVALUE('产品明细'[产品名称]), 
        CALCULATE( 
            VALUES('产品明细'[产品名称]), 
            '产品明细'[零售价]=199
        ) 
    ) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    在这里插入图片描述

    3.2.4.5 时间智能函数

    时间智能函数是一类函数的统称,也是数据分析中最常用的独立变量,在进行时间相关的分析时十分有用。
    1.Power BI中的时间智能函数

    class="table-box">
    时间智能函数说明
    DATESMTD/DATESQTD/DATESYTD月/季/年初至今
    FIRSTDATE/LASTDATE第一个日期/最后一个日期
    PREVIOUSDAY/MONTH/QUARTER/YEAR上一日/月/季/年
    NEXTDAY/MONTH/QUARTER/YEAR次日/月/季/年
    ENDOFMONTH/QUARTER/YEAR月/季/年度的最后一天
    STARTOFMONTH/QUARTER/YEAR月/季/年度的第一天
    SAMEPERIODLASTYEAR上年同期
    DATEADD移动一定间隔后的时间段
    DATESBETWEEN从起始日到结束日的时间段
    DATESINPERIOD从指定日期移动一定间隔的时间段
    PARALLELPERIOD移动指定间隔的完整粒度的时间段
    TOTALMTD/TOTALQTD/TOTALYTD月/季/年初至今,内置CALCULATE
    CLOSINGBALANCEMONTH/QUARTER/YEAR月/季/年度的期末数据,内置CALCULATE
    OPENINGBALANCEMONTH/QUARTER/YEAR月/季/年度的期初数据,内置CALCULATE

    根据时间智能函数返回的结果,可以时间智能函数分为两类。

    2.返回表的时间智能函数

    以上大部分函数只需要使用一个日期参数就可以,返回对应的时间区间,一般结合CALCULATE函数使用。

    3.返回值的时间智能函数

    以上函数可以对重置后的下上文执行运算,省掉了CALCULATE函数。

    例如求年初至今的销量,使用TOTALYTD函数:

    =TOTALYTD([数量],日期表[日期]) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    与使用DATESYTD函数的效果等同:

    =CALCULATE([数量],DATESYTD(日期表[日期])) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    4.涉及年度的时间智能函数的特殊用法

    以上8个函数的参数中最后都有一个可选参数,意思是年度结束日期,默认情况下就是自然年度的结束日期12月31日,可以省略,在特定的分析中,若年度结束日期不是12月31日,可以使用这个参数来界定。

    5.时间智能函数和普通函数的区别

    3.3 VAR变量

    VAR是VARIABLE的缩写,意为变量。

    3.3.1 VAR语法

    VAR的语法规范就是把一个表达式定义为一个名称:

    VAR 变量名=表达式 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    其中变量名不能和模型中现有的表名、字段名相同,也不能使用数字作为第一个字符,不能使用空格、不能使用中文等。

    定义变量是为了使用,可以使用RETURN来返回结果。

    3.4 常用的数据分析

    3.4.1 占比问题

    计算个体占总体的比例是一个很常见的分析方式,即两个数字相除。可以用ALL函数计算出汇总数据作为分母。

    以某网上商城的电子产品的销售记录数据为例,根据销售额指标来计算某产品的占总体或者类别的比例。

    首先写一个基础的销售金额度量值:

    销售金额 = SUM('订单'[销售额]) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
    3.4.1.1 总体占比

    计算总体占比,就是用每一个类别的销售额除以总计销售额。计算总计销售额,可以用ALL函数清除外部上下文的筛选,先单独计算出总计销售额:

    销售额总计= CALCULATE([销售金额],ALL('产品表')) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    新建一个度量值,用于计算占总体比例:

    总体占比 =  
    DIVIDE( 
        [销售金额], 
        CALCULATE([销售金额],ALL('产品表')) 
    ) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    将产品名称和产品类别放入矩阵的行中,度量值“销售金额”和“总体占比”放入矩阵的值中:

    3.4.1.2 分类占比

    每一种产品相对于总体的比例计算出来了,但是如果还需要知道每一种产品占所属分类的比例,新建一个度量值表示分类占比:

    分类占比 =  
    DIVIDE( 
        [销售金额], 
        CALCULATE([销售金额],ALL('产品表'[产品名称])) 
    ) 
     class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

    将这个度量值放入矩阵中,得到分类占比:

    未完待续

    注:本文转载自blog.csdn.net的STARBLOCKSHADOW的文章"https://blog.csdn.net/qq_41084756/article/details/143211838"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
    复制链接

    评论记录:

    未查询到任何数据!