PowerBI笔记 - 孙兴华火力全开

一. 界面认识与矩阵表操作

1.获取excel数据

菜单栏获取数据/首页从Excel导入数据 -> 选中表 -> 如果数据已清洗完毕可直接点加载,如果没有可点击转换数据进入PowerQuery数据清洗)

左侧菜单栏分别是:报表(可视化)、表格(查看表格内容)、模型

e.g.视觉对象选中饼图,姓名拖放到图例,分数拖放到值

2.菜单按钮

主页常用按钮:获取数据

建模常用按钮:

3.可视化常用的矩阵表(数据透视表)

e.g.行上放班级和姓名,列上放科目,值上放分数

选中报表 -> 点击设置视觉对象格式

#1 放大字体

#2 设置行高

#3 设置自动列宽

#4 筛选

筛选器拖放字段按需进行筛选

#5 居中显示

行标题对齐方式选择居中;特定列 -> 值,对齐方式选择居中

#6 层级加号显示

搜索"+"

#7 行标题缩进

搜索“缩进”

#8 层级分列展示

搜索“渐变”,关闭渐变布局按钮

效果:

#9 行小计和列小计

可选择关闭行小计或列小计,以及修改小计名称

关闭行小计效果:

#10 单元格元素(旧版名称:条件格式)

最常用的是“数据条”,比如可用于制作销售占比、销售金额时,效果:

“图标按钮”效果:

二. 运算符和新建列

1.运算符

运算符

含义

运算符

含义

运算符

含义

+

=

等于

&&

-

>

大于

||

*

<

小于

not

/

>=

大于等于

&

字符串连接

^

<=

小于等于

in

包含

<>

不等于

not in

不包含

2.新建列

打开表格,可以在表工具新建列,也可以在主页找到“新建列”按钮

新建列 -> 新列命名 -> 新列表达式(英文输入法输入单引号即可引用表字段)

引用列的方式:

除了输入单引号,也可以输入中括号。

新的销售量 = [销售数量]*10

新的销售量 = '销售表'[销售数量]*10

两种方法功能相同,什么时候引用列的时候必须带表名呢?

销售金额 = [销售数量]*RELATED('商品'[进价])

=> 在销售表新建销售金额列,[销售数量]来自销售表,[进价]来自商品表,不指明的话,不指明的话表达式不知道去哪张表取[进价]

总结:新建列的时候,当另一个需要计算的列来自其他表时,一定要指明表名。

为了避免出错,以后都采用单引号的方式引用列,在任何情况下都指明表名。

三. 建模与关系函数

1.建模

导入多张表的时候要考虑模型:

-- 连线时建议把1端的表放上面,多端的表放下面

1对多的关系:一个商品只会有一种进价,但是会有多笔销售记录

箭头方向(传递方向):商品表指向销售表,代表商品表可以筛选销售表,销售表可以向商品表索取内容

=> SQL中的表关联

2.LOOKUPVALUE函数

-- 就是VLOOKUP

语法:LOOKUPVALUE(把哪张表的哪个列拿过来, 找那张表上的谁, 找自己表里的谁)

LOOKUPVALUE('A'[c], 'A'[a], 'B'[b])

-- 通过B表的b列关联A表的a列,从而获取A表中a对应的c列值

-- 通常用多端的表去V1端的表

e.g. 单价 = LOOKUPVALUE('商品表'[进价], '商品表'[品名], '销售表'[商品名称])

删除列:

右键列名,选择删除

3.RELATED函数和RELATEDTABLE函数

(1) RELATED函数:(多端找一端)(事实表找维度表)(数据表找基础表)

销售成本 = '销售表'[销售数量]*RELATED('商品表'[进价])

-- 销售数量来自销售表,销售表是多端;进价来自商品表,商品表是1端;销售表向商品表索取[进价]

e.g.实现商品表筛选销售表,比如查看商品表中的商品各卖了多少笔记录

订单数量 = COUNTROWS(RELATEDTABLE('销售表'))

使用RELATEDTABLE效果:

-- 每一个品名对应2笔订单

RELATED是多端找一端的引路人,RELATEDTABLE是一端找多端的引路人。

四. 度量值、CALCULATE引擎、CALCULATETABLE筛选表

1.度量值

新建度量值:

度量值体现筛选功能:

矩阵表 -> 行放日期(下拉选择日期,取消日期层次结构) -> 值放总销量

-- 度量值是不占内存的,需要的时候拿出来用;如果是新建列,数据量大的话很占内存

-- 度量值最大的优点是自带筛选功能;新建列是没有筛选功能的

-- 度量值在引擎中可以循环使用

2.筛选引擎CALCULATE

CALCULATE(表达式,[筛选器1],…)

在筛选器修改的上下文中对表表达式进行求值

-- 第一个参数是计算器,第二个参数是筛选器,筛选器可缺省

销售表新建3个度量值:

总销量 = SUM('销量表'[销售数量])

A产品销量1 = CALCULATE([总销量],'商品表'[品名]="A")

A产品销量2 = CALCULATE([总销量],'销售表'[商品名称]="A")

可视化界面查看:

矩阵表 -> 行上放商品表的品名,值上放销售表的总销量、A产品销量1、A产品销量2

-- 表达式使用销售表的商品名称时显示正确

-- 原因是商品表1对多指向销售表,商品表筛选销售表;所以行上放商品表时,筛选器要用销售表作为条件;如果筛选器想用商品表品名作为条件,则行上换成销售表的商品名称,同样可以实现功能

3.多条件CALCULATE与筛选表

(1)多条件筛选CALCULATE

-- 不同列

多条件 = CALCULATE([总销量],'商品表'[品名] = "A",'商品表'[进价] = 0.1)

-- 相同列

多条件1 = CALCULATE([总销量],'商品表'[品名] in {"A","B","C"})

多条件2 = CALCULATE([总销量],not '商品表'[品名] in {"A","B","C"})

(2)筛选表

CALCULATETABLE(表,筛选条件)

-- 与CALCULATE区别在于,可以多表运作筛选,最终返回一张表

e.g.

新表 = CALCULATETABLE('销售表','商品表'[品名]="A",'商品表'[进价]=0.1)

-- 返回销售表的内容,根据商品表的条件去筛选它

-- 新建表会出现在模型视图

4.度量值的存放

-- 不建议在每张表到处建,会很乱,建议存放在统一的地方

主页 -> 输入数据 -> 修改名称为“度量值”-> 加载 -> 在“度量值”表格中新建度量值 -> 表格里有度量值之后删除空列

五. 高级筛选器FILTER与VALUES人工造表

-- 返回一个表,用于表示另一个表或表达式的子集,不能单独使用

FILTER函数对筛选的表进行横向的逐行扫描,这样的函数叫迭代函数。

FILTER是一个表函数,以后如果遇到表函数不知道怎么用的话,可以先放到新建表里测试一下,FILTER效果:

使用举例:

COUNTROWS(FILTER(表,筛选条件))

CALCULATE(表达式(度量值),FILTER(表,筛选条件))

-- 导入课件材料后发现“花名册”的列名都是“COLUMN”,第一行数据才是可识别的列名

右键“花名册” -> 编辑查询 -> 将第一行提作标题 -> 关闭并应用

由于两张表都有列名“学号”,所以在模型视图自动建立了连接

1.效果相同,为什么使用FILTER函数

总分 = SUM('成绩表'[分数])

1班男生1 = CALCULATE('度量值'[总分],'花名册'[班级]="1",'花名册'[性别]="")

1班男生2 = CALCULATE('度量值'[总分],FILTER('花名册','花名册'[班级]="1"&&'花名册'[性别]=""))

报表视图选择矩阵表,值上放“1班男生1”和“1班男生2”效果:

-- 两个公式效果是等价的

2.什么时候使用FILTER函数

在CALCULATE函数中的直接筛选条件里,我们只能输入:

'表'[列] = 固定值 (或>, <, >=, <=, <>, in, not in固定值)

但是遇到如下情况,就要使用FILTER函数:

[]=[度量值][]=[公式][]=[]

[度量值]=[度量值][度量值]=[公式][度量值]=固定值

举例:总分大于250分的学生一共考了多少分?

FILTER总分1 = CALCULATE('度量值'[总分],FILTER('花名册','度量值'[总分]>250))

FILTER总分2 = CALCULATE('度量值'[总分],FILTER('成绩表','度量值'[总分]>250))  --错误

矩阵表行上放姓名,值上放“FILTER总分1”和“FILTER总分2”效果:

“FILTER总分2”错误原因:

FILTER有一个严格要求,FILTER第一参数的表必须是唯一值的表,不能是多端数据的表

如果我只有一张表怎么办?我没有唯一表,只有数据表!那就自己造一张表!

=> VALUES人工造表

3.VALUES人工造表

FILTER总分3 = CALCULATE('度量值'[总分],FILTER(VALUES('成绩表'[学号]),'度量值'[总分]>250))

VALUES也是表函数,拿到新建表里做测试:

-- 提取出了成绩表中“学号”的唯一值

矩阵表值上加上“FILTER总分3”效果:

-- 效果和“FILTER总分1”一致

经典语句:CALCULATE([度量值],FILTER(VALUES('表'[列名]),筛选条件))

六. 被翻译耽误的上下文

1.上下文

同样一个公式,写在[新建列]和[度量值]中效果不一样。

-- 新建度量值

总分 = SUM('成绩表'[分数])

矩阵表行放[学号],值放[总分]效果:

-- 每个人都可以实现筛选功能

-- 在成绩表新建列

总分列 = SUM('成绩表'[分数])

-- 每一行都显示新建列表达式的结果,即整张成绩表的总分

这就是上下文,新建列是行上下文(逐行扫描,数求出来之后每一行都显示这个数),而度量值是筛选上下文(数值上可以进行筛选)。

如果想让新建列实现筛选功能需要套上CALCULATE:

总分列2 = CALCULATE(SUM('成绩表'[分数]))

总结:

(1) 度量值天生具有筛选功能

(2) 新建列是行上下文,行上下文没有筛选功能

(3) 想让行上下文实现筛选功能就要在外面套一个CALCULATE

2.FILTER与上下文

FILTER总分1 = CALCULATE('度量值'[总分],FILTER('花名册','度量值'[总分]>250))    #正确

FILTER总分4 = CALCULATE('度量值'[总分],FILTER('花名册',SUM('成绩表'[分数])>250))    #错误

矩阵表行上放班级,值上放“FILTER总分1”和“FILTER总分4”,效果:

-- FILTER4显示的是1班所有人的成绩、2班所有人的成绩、3班所有人的成绩以及总累计

-- 原因是SUM('成绩表'[分数])不是度量值,它只是一个聚合函数,只起到了计算的功能,不具备筛选功能

如果一定要采取公式的写法实现筛选功能,套上CALCULATE:

FILTER总分5 = CALCULATE('度量值'[总分],FILTER('花名册',CALCULATE(SUM('成绩表'[分数]))>250))

所谓的筛选上下文,就是度量值,度量值自带天然的CALCULATE函数;

没有筛选功能的新建列就是行上下文,如果行上下文向转成筛选上下文,它是不会自动转的,要手动套上一个CALCULATE函数。

七. ALL函数、ALLEXCEPT函数、ALLSELECTED函数

ALL函数

作用:清除筛选 => 指的是清除度量值的筛选功能,因为度量值天生就具备筛选功能

返回:清除筛选后的表格或列

语法:

ALL(表)

ALL(表[列])

新建度量值:

商品表中商品总数 = COUNTROWS('商品表')

销售表中商品数量 = CALCULATE(COUNTROWS('商品表'),'销售表')

-- 注意,此处CALCULATE的第二参数是表,表示从商品表中筛选出销售表中的商品;销售表的商品是包含在商品表里的,此处计算器计算商品总数,筛选条件是销售表

不能筛选的总数 = COUNTROWS(ALL('商品表'))

矩阵表行上放“商品编码”,值上放“商品表中商品总数”、“销售表中商品总数”、“不能筛选的总数”,效果:

如果行上放了“商品编码”,想要计算销售表的商品数量占商品表商品总数量的占比(虽然没有意义,要么1/26要么0/26),去除以“商品表中商品总数”是无法实现的,因为度量值自带筛选功能,每行的“商品表中商品总数”会根据“商品编码”筛选计算出来都是1,最终占比要么1/1要么0/1。“不能筛选的总数”使用ALL清除度量值的筛选功能,才能得到正确的占比。

占比 = '度量值'[销售表中商品数量]/'度量值'[不能筛选的总数]

案例一【应用于表】:计算销售表中每个商品的占比

总销量 = SUM('销售表'[销售数量])

禁止筛选的总销量 = CALCULATE('度量值2'[总销量],ALL('销售表'))

每个商品的占比 = '度量值2'[总销量]/'度量值2'[禁止筛选的总销量]

矩阵表行上放'销售表'[商品编码]:

-- ALL函数用得最多的地方就是计算占比的时候

报表视图添加切片器,筛选字段选择'销量表'[日期],设置日期区间为12.1-12.1,效果:

-- 切片器:用于过滤数据,实现数据动态展示

-- “总销量”仅展示12.1各产品销量汇总,“禁止筛选的总销量”还是展示的12.1+12.2的全产品总销量

-- 现希望总计占比保持100%

总结:

ALL函数参数为表时,忽略所有的筛选条件,无论是该图表内还是外部切片器。

ALLSELECTED函数替换ALL函数解决占比问题:

-- 将“禁止筛选的总销量”表达式中ALL替换为ALLSELECTED

禁止筛选的总销量 = CALCULATE('度量值2'[总销量],ALLSELECTED('销售表'))

-- 替换后切片器的筛选对“禁止筛选的总销量”生效,仅展示12.1的全产品总销量

-- ALLSELECTED除了保留来自外部的筛选器,和ALL没有任何区别,多用于显示百分比的时候

以上图例中,行上放的是'销售表'[商品编码],如果想放商品名称,换成'商品表'[商品名称]:

-- 部分产品如A在销售表是没有销量的,但是因为ALL函数是不受内部筛选影响的,所以“禁止筛选的总销量”列都显示了值

解决方法有2种:

(1) 清除矩阵表值上的“禁止筛选的总销量”

(2) 到销售表里把商品表的商品名称VLOOKUP过来

销售表新建列:

商品名称 = LOOKUPVALUE('商品表'[商品名称],'商品表'[商品编码],'销售表'[商品编码])

报表视图矩阵表行上放'销售表'[商品名称]:

案例二【应用于列】:

-- 由于销售表中没有大类这个列,我们先把大类V过来再测试

【销售表新建列】

大类 = LOOKUPVALUE('商品表'[大类],'商品表'[商品编码],'销售表'[商品编码])

【销售表新建列】

规格 = LOOKUPVALUE('商品表'[规格],'商品表'[商品编码],'销售表'[商品编码])

【度量值】

取消列筛选 = CALCULATE('度量值2'[总销量],ALL('销售表'[规格]))

报表视图行上放'销售表'[大类],值上放'度量值2'[总销量]、'度量值2'[取消列筛选];添加切片器,字段添加'销售表'[日期](视觉对象格式 -> 切片器设置 -> 选项 -> 样式选为垂直列表);添加切片器,字段添加'销售表'[规格]:

-- 用“日期”筛选时,“取消列筛选”值发生变化,即外部筛选器生效

-- 用“规格”筛选时,“取消列筛选”值保持不变,即外部筛选器不生效

总结:

当ALL函数参数为列时,忽略该列筛选,图表内部其他字段或外部筛选其他字段会产生作用。

注意:

ALL函数在引用列的时候,必须与矩阵表的行和列在同一张表。

比如矩阵表的行和列都来自于销售表,那么ALL函数引用列的时候,也必须引用销售表的列,like ALL('销售表'[规格]),不能从商品表拿规格,必要时使用LOOKUPVALUE先把需要的字段V过来。

ALL函数引用列的使用场景:

【新建度量值】

占比 = '度量值2'[总销量]/'度量值2'[取消列筛选]

矩阵表行上放'销售表'[大类]、'销售表'[规格],值上加上'度量值2'[占比]:

-- 展示袋装占比、盒装占比 -> 可用于计算分类占比

ALLEXCEPT函数:除之外

语法:ALLEXCEPT('表名'[列名])

-- 除了参数列以外的列,全部取消筛选

-- 等同于ALL('表名'[列名1],'表名'[列名2],'表名'[列名3],…)

八. ALLNOBLANKROW核对数据

-- 返回表中除空白行以外的所有行或列中的所有值

【新建表】

测试表1 = ALLNOBLANKROW('子表')

-- 子表中无重复的行或空白行,所以全部返回

测试表2 = ALLNOBLANKROW('子表'[姓名])

-- 返回子表中去重后的所有姓名

-- 返回:去重(即便只有一列,它也是表)

【新建度量值】

行数1 = COUNTROWS('子表')

行数2 = COUNTROWS(ALL('子表'))

行数3 = COUNTROWS(ALLNOBLANKROW('子表'))

矩阵表行上放'子表'[姓名],值上放'度量值2'[行数1]、'度量值2'[行数2]、'度量值2'[行数3]:

把行换成'父表'[姓名]:

-- 出现空行,因为父表里没有唐僧

【案例】

【新建度量值】

总销量 = SUM('销售表'[销售数量])

ALL总销量 = CALCULATE('度量值'[总销量],ALL('商品表'))

ALLNOBLANKROW总销量 = CALCULATE('度量值'[总销量],ALLNOBLANKROW('商品表'))

矩阵表行上放'销售表'[名称],值上放3个度量值:

-- 键盘存在于销售表中,但不存在于商品表中,通过ALLNOBLANKCOUNT一眼看出哪些东西是商品表没有但是被卖出去的

-- 一般人工造出来的数据才会发生这种情况,计算机记录的数据是不会发生的

九. 聚合函数和迭代函数

1.聚合函数

语法:

-- 参数是物理列

总钱数 = SUM('表'[捡钱])

平均钱数 = AVERAGE('表'[捡钱])    -- 算出平均值

-- AVERAGE是数值总和除以数值的个数,AVERGAEA是数值总和除以项数

最大值 = MAX('表'[捡钱])

最小值 = MIN('表'[捡钱])

记录数 = COUNTROWS('表')

人数 = DISTINCTCOUNT('表'[姓名])    -- 去重计数

COUNTA函数:计算列中单元格不为空的数目

COUNTBLANK函数:计算列中单元格为空的数目

PRODUCT函数:计算列中单元格乘积

2.迭代函数

【新建列】

净值 = ''[捡钱]-''[丢钱]

= SUMX('',''[捡钱]-''[丢钱])

2 = CALCULATE(SUMX('',''[捡钱]-''[丢钱]))

计算过程:

对每一行逐行扫描,比如

第一行,1-0.1=0.9

第二行,2-0.9=1.1

第五行,5-0.8=4.2

将所有值求和。因为新建列是行上下文,不具备筛选功能,所以上图所有行对应的[列]都是最后的的总和12.8。

如果没有SUMX函数:

净值  =  '捡钱'-'丢钱'

求和 = SUM('净值')

语法:SUMX(表,算术表达式)

解释:将每一行按算术表达式计算后,再将计算结果求和。

AVERAGEX、MAXX、MINXX、COUNTX、COUNTAX、PRODUCTX……它们和FILTER函数一样都是行上下文函数

十. EARLIER函数【当前行】

案例一:计算下一个订单日期

【新建列】

下个订单日期 = SUMX(FILTER('',''[序号]=EARLIER(''[序号])+1),''[销售日期])

分析:

EARLIER('表'[序号])+1  

-- 当前行序号+1

FILETER('表','表'[序号]=EARLIER('表'[序号])+1)  

 -- 将“序号等于当前行序号+1”的表筛选出来

SUMX(FILETER('表','表'[序号]=EARLIER('表'[序号])+1),'表'[销售日期])   

-- 这里用哪个迭代函数都可以,没有求和求平均的操作,仅用来迭代返回销售日期(不理解)

案例二:累计求和

累计求和 = SUMX(FILTER('',''[序号]<=EARLIER(''[序号])),''[销售量])

分析:

将“序号小于等于当前行序号”的表筛选出来,因为肯定不止一行,所以用SUMX迭代求和。

案例三:分组累计求和

商品累计求和 = SUMX(FILTER('',''[序号]<=EARLIER(''[序号])&&''[商品]=EARLIER(''[商品])),''[销售量])

分析:

将“序号小于等于当前行序号”且“商品等于当前行商品”的表筛选出来,求和。

表中没有序号,可以用日期,比如:累计计算电视每天的累加值,手机每天的累计值:

商品累计求和 = SUMX(FILTER('',''[销售日期]<=EARLIER(''[销售日期])&&''[商品]=EARLIER(''[商品])),''[销售量])

案例四:累计购买次数

第几次购买 = COUNTROWS(FILTER('1','1'[姓名]=EARLIER('1'[姓名])&&'1'[序号]<=EARLIER('1'[序号])))

分析:

将“序号小于等于当前行序号”且“姓名等于当前行姓名”的表筛选出来,计算行数。

十一.  VALUES与DISTINCT区别

1.VALUES函数

VALUES(表[列]):

表1 = VALUES('表'[姓名])    -- 把姓名不重复的列提取出来,形成一个单列的表;人造基础表(单列)

VALUES(表):

表2 = VALUES('表')    -- 返回表的所有行,就是复制一张表;人造虚拟表,建立虚拟关系的时候用到

2.DISTINCT函数

DISTINCT(表名[字段名])    -- 返回:去重后,唯一值的列

DISTINCT(表名)    -- 返回:只包含非重复行的表

DISTINCT(返回表的表达式)

2 = DISTINCT(FILTER('1','1'[性别]=""))

3.区别

(1) 对于空白行的处理上,VALUES包括没有匹配的空白行,DISTINCT不返回没有匹配的空白行

空白行的专业术语:参照完整性不匹配

=> 说人话:销售表上有的数据,基础表上没有;比如销售表卖出了A04商品,商品表没有A01(现实中不可能发生)

【新建度量值】

行数 = COUNTROWS('商品表')

VALUES编码 = COUNTROWS(VALUES('商品表'[商品编码]))

DISTINCT编码 = COUNTROWS(DISTINCT('商品表'[商品编码]))

VALUES进价 = COUNTROWS(VALUES('商品表'[进价]))

DISTINCT进价 = COUNTROWS(DISTINCT('商品表'[进价]))

矩阵表值上放5个度量值:

-- VALUES出现了空白行,DISTINCT正确

-- 因为在模型视图中,商品表和销售表建立了关系,A04不在商品表里,但在销售表里,VALUES也会把它算作一行;DISTINCT排除该问题,不返回

(2) DISTINCT函数允许列名或任何有效的表表达式作为其参数,但VALUES函数仅接受列名或表名作为参数

十二. 条件判断函数【基础】

1.IFERROR【遇到错误时使用指定数值替换】

 

销售金额 = IFERROR('1'[销售数量]*'1'[单价],BLANK())

-- 如果表达式遇到错误则返回空

销售金额 = IFERROR('1'[销售数量]*'1'[单价],"不能计算")    错误!!!

-- IFERROR只能返回空或者数值

销售金额 = IFERROR('1'[销售数量]*'1'[单价],0)

2.IF条件判断

IF(条件, A, [B])

检查是否满足条件,如果为 TRUE 则返回A,如果为 FALSE 则返回B;

B可以省略不写,省略时返回为空,比如满足某个分数时返回“优秀”,不满足的时候不写。

IF适合条件比较少的时候使用,如果条件太多,嵌套太多,不方便使用。

案例一:

【新建列】

称呼 = IF('2'[性别]="","先生","女士")

案例二:

间隔 = IF('5'[取款日期]=BLANK(),BLANK(),'5'[取款日期]-'5'[存款日期])

-- 默认返回日期类型,列工具 -> 数据类型 -> 整数,即可显示为整数

3.SWITCH多项条件判断

SWITCH(表达式, 值1, 结果1, 值2,  结果2, ..., [else])

根据表达式的值返回不同结果;最后一个参数可以省略不写,代表以上值都不满足会返回什么,省略时返回为空。

案例:

月份 = SWITCH('3'[],

1, "1", 2, "2",

3, "3", 4, "4",

5, "5", 6, "6",

7, "7", 8, "8",

9, "9", 10, "10",

11, "11", 12, "12",

"未能识别")

SWITCH特殊用法:

使用TRUE作为第一参数的作用是,返回条件判断列表中第一个为TRUE的结果。

-- 如果是多个字段同时判断:'例4'[年龄]<30 && '例4'[性别]="男"

年龄段 = SWITCH(TRUE(),

'4'[年龄]<30,"30岁以下",

'4'[年龄]<40,"30-40",

'4'[年龄]<50,"40-50",

"50岁以上")

-- 比如35,第一个为TRUE是在判断<40的时候,所以返回“30-40岁”,后面的条件不看了

十三. 安全除法DIVIDE与按层级计算ISINSCOPE函数

1.安全除法

语法:DIVIDE(分子,分母,[替换结果])

替换结果可以省略不写,省略时返回为空。

除法 = [分子]/[分母]

-- 分母为0 时返回无穷大

安全除法 = DIVIDE(分子,分母,BLANK())

安全除法 = DIVIDE(分子,分母,0)

2.按层级计算ISINSCOPE函数

ISINSCOPE函数的意思:是否在范围内

官方释义:当指定的列是级别层次结构中的级别时,返回true。

【新建度量值】

层级占比 = SWITCH(TRUE(),

ISINSCOPE('商品表'[商品名称]),DIVIDE('度量值'[总金额],CALCULATE('度量值'[总金额],ALL('商品表'[商品名称]))),

ISINSCOPE('商品表'[产品类别]),DIVIDE('度量值'[总金额],CALCULATE('度量值'[总金额],ALL('商品表'[产品类别]))),

DIVIDE('度量值'[总金额],CALCULATE('度量值'[总金额],ALL('商品表'[商品名称])))

)

矩阵表行上放('商品表'[产品类别]'商品表'[商品名称] -> 产生了层级关系,值上放'度量值'[层级占比]:

-- 判断当前行是否属于[产品类别]层级,如果是,则计算该产品类别总销量占所有产品类别总销量的占比;比如:手机类总销量占所有产品类别总销量的46%

-- 判断当前行是否属于[产品名称]层级,如果是,则计算该产品名称总销量占其父层级下所有产品总销量的占比;比如:小米10占手机类产品总销量的7%

-- 如果既不是[产品名称]级别,又不是[产品类别]级别,则直接计算(可以不写,如果不写,总计行为空)

-- 层级关系跟数据源表没有关系,主要取决于拉矩阵的时候行那一栏怎么放

十四. ISCROSSFILTERED函数和ISFILTERED函数的区别

语法:

ISFILTERED(TableNameOrColumnName)

在存在针对指定列的直接筛选器时,返回 true。

-- 只有对指定列筛选时才返回true

ISCROSSFILTERED(TableNameOrColumnName)

在对指定表或列进行交叉筛选时,返回 true。

-- 对表中任意列进行筛选都会返回true

【新建表】

日期表 = ADDCOLUMNS(

CALENDAR(DATE(2019,1,1),DATE(2021,12,31)),

"",YEAR([Date]),

"",MONTH([Date]),

"",WEEKNUM([Date]),

"年季度",YEAR([Date])&"Q"&ROUNDUP(MONTH([Date])/3,0),

"年月",YEAR([Date])*100+MONTH([Date]),

"年周",YEAR([Date])*100+WEEKNUM([Date]),

"星期几",WEEKDAY([Date])

)

 

【新建度量值】

ISFILTERED测试 = ISFILTERED('日期表'[Date])

ISCROSSFILTERED测试 = ISCROSSFILTERED('日期表'[Date])

报表视图添加切片器,字段使用'日期表'[年月];添加矩阵表,值上放2个度量值:

-- 不筛选年月

-- 筛选年月

# 因为没有对指定的'日期表'[Date]做筛选,所以“ISFILTERED测试”为FALSE

# 因为对'日期表'做了筛选,所以“ISCROSSFILTERED”为TRUE

案例:实现切片器筛选日期后,展示指定日期倒推12个月的销量数据

【日期表新建列】

年月序号 = SWITCH(

TRUE(),

'日期表'[]=2019,0+'日期表'[],

'日期表'[]=2020,12+'日期表'[],

'日期表'[]=2021,24+'日期表'[]

)

【新建度量值】

12个月 = IF(

ISCROSSFILTERED('日期表'[年月]),

CALCULATE(VALUES(''[年月]),FILTER('',''[年月序号]<=MAX('日期表'[年月序号])&&''[年月序号]>MAX('日期表'[年月序号])-12)),

1

)

-- CALCULATE第一参数可以是一张表,表是计算器,后面筛选这张表的条件就是筛选器

-- VALUES('表'[年月])得到表里年月不重复的值

-- 使用FILTER的原因是需要列和列的比较,CALCULATE默认的筛选器只支持和固定值的比较

-- 不理解这里MAX的作用,尝试不使用MAX直接和'日期表'[年月序号]比较,发现Power BI无法找到'日期表'及其字段(原因未知),且手动输入后报错:

-- 不能直接对比的原因:[年月]在'日期表'中不是唯一值,即使'日期表'过滤出一个[年月]值,还是会对应多个[年月序号](比如选择201901,在日期表中对应了多行数据,也就意味着有多个年月序号,虽然它们的[年月序号]相同,都是1),公式无法确定单个值

-- MAX换成MIN、AVERAGE是一样的效果

报表视图添加切片器,字段使用'日期表'[年月];添加矩阵表,行上放'表'[年月](只能放'表'里的,不能放'日期表'里的,因为两张表没有连线),值上放'表'[销售金额];选中矩阵表 -> '度量值'[12个月]放到筛选器里 -> 条件为“不为空” -> 应用筛选器

-- 外部筛选器[前12个月]条件设置成“不为空”:切片器选择201903,则矩阵表值显示201901-201903的销量数据,不满足范围的就不显示

十五. FIRSTNONBLANK与LASTNONBLANK函数

-- FIRSTNONBLANK函数与LASTNONBLANK函数属于表函数,有些时候也可以作为值函数使用

语法:

FIRSTNONBLANK(<列>,<表达式>)

返回列中表达式具有非空白值的第一个值

LASTNONBLANK(<列>,<表达式>)

返回列中表达式具有非空白值的最后一个值

<列>:任何列,或者具有单列的表,也可以是表达式

<表达式>:计算空值的表达式,也就是判定条件

返回结果:单列的表,只有一行数据(也就是只有一个返回值,只不过这个值在表中)

案例一:应用于表函数

【新建

2 = FIRSTNONBLANK(''[日期],CALCULATE(SUM(''[销售])))

-- 求出产生第一笔销售额的日期

-- 表达式可以用度量值或者嵌套CALCULATE,否则会导致计算忽略计算筛选上下文,只考虑行上下文,那么呈现的结果将是2020年1月1日(最小的日期);即不套CALCULATE,每一行对应的表达式值就都是SUM起来的总销售,不是根据日期和姓名筛选后的了

总结:第二个参数的表达式要具备筛选功能

案例二:应用于值函数

-- 求出每个人第一笔销售的销售额

【新建度量值

每个人第一个不为空的销售 = CALCULATE(

SUM(''[销售]),

FIRSTNONBLANK('表'[日期],CALCULATE(SUM('表'[销售])))

)

-- 将案例一的表放到CALCULATE筛选器里,用于筛选每个人第一个有销售的日期所产生的销售额

矩阵表行上放'表'[姓名],值上放'度量值'[每个人第一个不为空的销售]

十六. 进阶条件判断函数

1.HASONEFILTER函数【判断是否被筛选】

语法:HASONEFILTER(列名)

HASNOFILTER是被直接筛选影响的。

当指定的列有且只有一个由直接筛选产生的值时,返回true。参数必须使用物理列(表里有什么列就用什么列,可以新建列),不支持表达式。

案例一:

【新建度量值】

总分 = SUM('案例1'[成绩])

HASONEFILTER总成绩 = IF(HASONEFILTER('案例1'[姓名]),[总分],BLANK())

矩阵表行上放'案例1'[姓名],值上放'案例1'[成绩];切片器字段上放'案例1'[姓名];新矩阵表行上放'案例1'[老师],值上放'案例1'[HASONEFILTER总成绩]

-- 指定的列有且只有一个由直接筛选产生的值,HASONEFILTER返回true,IF语句返回总分

-- 指定的列有多个由直接筛选产生的值,HASONEFILTER返回false,IF语句返回BLANK()

案例二:

【新建度量值】

总金额 = SUM('案例2'[销售金额])

-- 如果'案例2'[销售金额]是外汇

外汇转人民币 = IF(HASONEFILTER('汇率'[货币]),FIRSTNONBLANK('汇率'[汇率],1)*'案例2'[总金额],BLANK())

-- 此处的FIRSTNONBLANK函数由于只需要取第一个不为空的值,不牵涉表达式,这种情况第二个参数可以写1,也可以写两个英文双引号"",都代表第二个条件不要,什么都不做,只取汇率里面的第一个

-- 效果:只可以选择一种货币类型进行汇率转换,如果同一个货币类型有多个汇率值,则取第一个;不支持选择多种货币类型进行汇率转换,如果选了多个,则返回空

切片器字段上放'汇率'[货币]用于筛选,矩阵表行上放'案例2'[日期](下拉选择日期,取消层次结构),值上放'案例2'[总金额]、'案例2'[外汇转人民币]

-- -- 如果'案例2'[销售金额]是人民币

人民币转外汇 = IF(HASONEFILTER('汇率'[货币]),DIVIDE('案例2'[总金额],FIRSTNONBLANK('汇率'[汇率],1)),BLANK())

2.HASONEVALUE函数【判断是否只有一行数据】

语法:HASONEVALUE(列名)

通常和IF函数搭配使用,判断某列是否只有一行数据。

经典语句:IF(HASONEVALUE('表名'[列名]),[度量值],BALNK())

案例:

-- 只有一个学生的老师,他们的学生考了多少分

【新建度量值】

总分 = SUM('案例1'[成绩])

姓名唯一的人的分数 = IF(HASONEVALUE('案例1'[姓名]),'案例1'[总分],BLANK())

矩阵表行上放'案例2'[老师],值上放'案例2'[姓名唯一的人的分数]

-- 因为李小龙和叶问这两个老师是唯一的没有重复的,只对应一个学生,所以只显示他们的分数

-- 总计不显示,一般当不想要总计的时候,才会用HASONEVALUE函数,平时用不到

【扩展知识】DATATABLE人工建表

手工建表 - 菜单栏“输入数据“

参数表1 = DATATABLE("字段名",数据类型,{{数据1},{数据2}})

数据类型:INTEGERDOUBLESTRINGBOOLEANCURRENCYDATETIME

多字段这样写:

参数表2 = DATATABLE("字段名1",数据类型1,"字段名2",数据类型2,{{数据11,数据12},{数据21,数据22}})

-- 数据11和数据22分别是字段1和字段2的值,以行显示;数据11和数据12是第一行,数据21和数据22是第二行

3.SELECTEDVALUE函数

当指定列只有一个值时返回该值,否则返回替代结果,省略替代结果时返回空值

语法:

SELECTEDVALUE('表名'[列名],[替代结果(省略返回空)])

案例:

-- 实现切片器选择销售量时,报表显示销售量;切片器选择销售额时,报表显示销售额

【新建表】

参数表 = DATATABLE("字段名",STRING,{{"销售量"},{"销售额"}})

切片器字段上放'参数表'[字段名],簇状柱形图X轴放'案例3'[商品名称],Y轴放'案例3'[销售量]、'案例3'[销售金额]

-- 此时切片器选择销售额,柱形图依旧同时显示销售额和销售量

【新建度量值】

= SWITCH(SELECTEDVALUE('参数表'[字段名]),"销售额",SUM('案例3'[销售金额]),"销售量",SUM('案例3'[销售量]))

簇状柱形图Y轴换成'案例3'[值]:

十七. 转换函数

1.CURRENCY函数【数字转货币】

作用:将表达式结果转换为货币类型

【新建列】

列 = CURRENCY('CURRENCY'[数值1])

-- "文本1"数据类型改成文本,"日期"数据类型改成日期

2.INT函数【向下舍入】

作用:将表达式转换为整数(向下舍入

说人话:

当数值为正数时,取整数抹

当数值为负数时,凑零补整

【新建列】

= INT('INT'[数值])

3.TRUNC函数【直接取整】

【新建列】

= TRUNC('TRUNC'[数值])

4.ROUND函数【四舍五入】

语法:

ROUND(数值,保留小数点的位数)

【新建列】

= ROUND('ROUND'[数值],4)

5.MROUND函数【取数值的倍数】

语法:

MROUND(数值,哪个数的倍数)

-- 两个参数的小数点位数必须一致

-- 符号必须一致

MROUND(1.3,0.2) => 1.4

-- 从1.3开始往上找0.2的倍数,最近的是1.4

MROUND(-10,-3) => -9

-- 从-10开始往上找-3的倍数,最近的是-9

MROUND(5,-2) => ERROR

【新建列】

= MROUND('MROUND'[数值],5.00)

-- 在6.05附近找2.00的倍数,最近的是6;在7.05附近找2.00的倍数,最近的是8???

6.日期和时间的转换

DATE(年,月,日)

TIME(小时,分钟,秒)

【新建列】

= DATE('Date'[],'Date'[],'Date'[])

-- 数据类型选择日期

= TIME('Time'[],'Time'[],'Time'[])

7.CONVERT函数【转换为指定数据类型】

语法:

CONVERT(表达式,数据类型)

数据类型:

INTEGER整型、DOUBLE双精度、STRING字符、BOOLEAN布尔、CUREENCY货币、DATETIME日期时间

【新建列】

= CONVERT('CONVERT'[销售数量]*'CONVERT'[单价],STRING)

8.DATEVALUE函数【文本格式的日期转成日期时间格式的日期】

【新建列】

= DATEVALUE('DATEVALUE'[文本日期])

-- 数据类型改成日期,否则带时间,因为默认转成日期时间格式

9.TIMEVALUE函数【文本格式的时间转成日期时间格式的时间】

【新建列】

2 = TIMEVALUE('Time'[]

-- 为了测试,列的数据类型改成文本

-- 列2数据类型改成日期,否则带日期,因为默认转成日期时间格式

10.VALUE函数【文本转数值】

语法:

VALUE(<文本>)

返回结果:数值类型,十进制数字

-- 如果文本不是数字、日期或时间格式,则返回错误。

【新建列】

6 = VALUE('CURRENCY'[文本1])

十八. FORMAT函数【格式化】

语法:

FORMAT(数值或日期,格式)

将值转换为指定格式的文本,通常与DATETIME格式一起使用

【新建列】

= FORMAT(DATE('Date'[],'Date'[],'Date'[]),"yyyymmdd")

具体格式详见官方文档:

FORMAT 函数 (DAX) - DAX | Microsoft Learn

注意几个特殊情况:

1.在格式中输入的字符串要加两个双引

= FORMAT(DATE('Date'[],'Date'[],'Date'[]),"""孙兴华"" yyyy")

2.转义字符

= FORMAT(DATE('Date'[],'Date'[],'Date'[]),"yyyy \Qq")

-- Q代表季度,属于格式关键字,想要显示"Q"需要加转义字符反斜杠\,否则Qq会显示两遍季度

3.自定义格式

= FORMAT(DATE('Date'[],'Date'[],'Date'[]),"dd/mm/yyyy")

= FORMAT(TIME('Time'[],'Time'[],'Time'[]),"h:nn:ss")

十九. 日期时间函数【非智能函数】

1.提取年月日时分秒、季度、当前时间

【新建列】

= YEAR(''[时间日期])

= MONTH(''[时间日期])

= DAY(''[时间日期])

= HOUR(''[时间日期])

= MINUTE(''[时间日期])

= SECOND(''[时间日期])

季度 = QUARTER(''[时间日期])

当前日期和时间 = NOW()

当前日期 = TODAY()

-- 可修改当前日期的数据类型为“日期”

2.星期和周

【新建列】

当周的第几天 = WEEKDAY(''[时间日期],2)

-- 从星期一开始算做一周的开始

不同国家对周几算当周的开始有不同的规定:

-- 第二个参数 = 1

-- 第二个参数 = 2

-- 第二个参数 = 3

【新建列】

当年的第几周 = WEEKNUM(''[时间日期],2)

-- 第二个参数和WEEKDAY类似,用于规定哪天算一周的开始

3.平移指定月份

EDATE(日期,平移月数)

-- 返回按指定月份平移后的日期;正数向后,负数向前

EOMONTH(日期,平移月数)

-- 返回按指定月数平移后的月份的最后一天

举例:

EOMONTH(TODAY(),-1)    -- 代表今天的日期向前推一个月的月末日期

【新建列】

平移月份 = EDATE(''[时间日期],2)

平移月份月末日期 = EOMONTH(''[时间日期],2)

4.DATEDIFF间隔日期时间

DATEDIFF(起始日期, 结束日期, 间隔单位)

【新建列】

= DATEDIFF('2'[起始日期],'2'[结束日期],YEAR)

-- Tips: 如果计算保质期要+1,因为生产日期当天就算第一天了

5.YEARFRAC函数

-- 也是用来计算时间间隔的,比DATEDIFF更精确,比如可用于计算工龄

YEARFRAC(起始日期, 结束日期, <计算标准>)

【新建列】

= YEARFRAC('2'[起始日期],TODAY(),0)

-- 自行设置小数点位数

第二个参数:

-- 0

-- 1

-- 2

-- 3

-- 4

二十. 文本函数

1.CONCATENATE【将两个字符串连接】

语法:

CONCATENATE(<文本1 或 数字1>, <文本2 或 数字2>)

【新建列】

= CONCATENATE('CONCATENATE'[文本1], 'CONCATENATE'[文本2])

= CONCATENATE('CONCATENATE'[数字1], 'CONCATENATE'[数字2])

2.EXACT【判断字符是否相同】

语法:

EXACT(<文本1 或 数字1>, <文本2 或 数字2>)

【新建列】

= EXACT('CONCATENATE'[文本1], 'CONCATENATE'[文本2])

= EXACT('CONCATENATE'[数字1], 'CONCATENATE'[数字2])

应用场景举例:

配合IF语句,如果这两列内容一样返回什么,否则返回什么

3.FIND【找字符串在另一个字符串的起始位置】

返回一个文本字符串在另一个文本字符串中的起始位置;区分大小写;不支持通配符

语法:

FIND(<待查找内容>, <查找范围>, [<起始位置>], [<备选结果>])

[<起始位置>]:开始搜索的位置;如果省略,则起始位置为1,即从第一个字符开始找

[<备选结果>]:未找到文本时返回的值,可设为0、-1或BILANK();如果省略,则找不到时返回错误

【新建列】

= FIND('find'[子串], 'find'[字符串])

-- 将excel子串列的VBA改成小写,保存并刷新数据(PowerBI会重新加载数据),表达式报错

-- 传入<起始位置>和<备选结果>

= FIND('find'[子串], 'find'[字符串], 6, BLANK())

4.SEARCH【找字符串在另一个字符串的起始位置;不区分大小写;可用通配符

语法:

SEARCH(<待查找内容>, <查找范围>, [<起始位置>], [<备选结果>])

-- 语法和FIND相同

通配符:?代表一个字符,*代表多个字符

-- 不区分大小写

= SEARCH('find'[子串], 'find'[字符串])

-- 使用通配符

= SEARCH("孙?华", 'find'[字符串])

5.截取函数

语法:

LEFT([字段名], 取几个字符)    -- 从左向右取

RIGHT([字段名], 取几个字符)    -- 从右向左取

MID([字段名], 从第几个取, 取几个)    -- 从中间开始取

LEN([字段名])    -- 长度

【新建列】

= LEFT([字符串], 3)

= RIGHT([字符串], 3)

= MID([字符串], 3, 3)

= LEN([字符串])

6.FIXED【数值转字符;按指定小数位四舍五入】

将数值舍入到指定的小数位数,并将结果返回为文本;可以指定返回的结果是否包含千分符

语法:

FIXED(<数字>, [<小数位数>], [<逻辑值>])

[<逻辑值>]:如果为1,则不在返回的文本中显示千分符;如果为0或省略,则在返回的文本中显示千分符

【新建列】

= FIXED([数值], 3)

= FIXED([数值], 3, 1)

7.大小写转换

语法:

LOWER(<文本>)    -- 将文本字符串中的所有字母都转换成小写

UPPER(<文本>)    -- 将文本字符串中的所有字母都转换成大写

8.删除空格

删除文本前后的所有空格和单词之间多于一个的空格,保留单词之间的单个空格

语法:

TRIM(<文本>)

【新建列】

= TRIM([字符串])

如果要删除特定的空格,可以搭配截取函数LEFT()、RIGHT()、MID()并配合LEN()函数

9.重复字符串

语法:

REPT(<文本>, <重复次数>)    -- 按给定的次数重复文本

如果重复次数为0,REPT()返回空白;REPT()函数的结果不能超过32767个字符,否则将返回错误。

【新建列】

= REPT([字符串], 2)

= REPT([字符串], 0)

二十一. 替换函数

1.REPLACE【按指定位置替换字符串】

将指定位置的字符串转换为新的字符串

语法:

REPLACE(<文本>, <起始位置>, <替换长度>, <新内容>)

如果<替换长度>为空,或者引用包含空值的列,则新内容字符串插入到起始位置,不替换任何字符。

【新建列】

= REPLACE('REPLACE'[字符串], 3, 3, "孙兴华")

2.SUBSTITUTE【按指定内容替换字符串】

将指定的字符串替换为新的字符串;区分大小写

语法:

SUBSTITUTE(<文本>, <被替换内容>, <新内容>, [<匹配项>])

[<匹配项>]:代表替换第几个<被替换内容>,如果省略,则会替换所有找到的<被替换内容>

【新建列】

= SUBSTITUTE('SUBSTITUTE'[字符串], "孙兴华", "小孙")

二十二. 三角、数学、信息函数【不常用】

找一下老师的笔记

MOD【取余数】

返回指定数字被整除后的余数

语法:

MOD(<被除数>, <除数>)

二十三. 分组与连接函数

1.SUMMARIZECOLUMNS

是一种更灵活、更高效的SUMMARIZE实现方式。在编紫萼查询的时候,可以优先考虑SUMMARIZECOLUMNS。

语法:

SUMMARIZECOLUMNS(<groupBy_columnName1>, [<groupBy_columnName2>], …, [<filterTable>], …, [<name>, <expression>], …)

-- GroupBy_columnName参数描述里的可重复代表可以有多个分组依据

案例一:返回不重复姓名

原表:

【新建表】

不重复姓名 = SUMMARIZECOLUMNS('重复姓名'[姓名])

案例二:返回多列不重复

原表:

【新建表】

多列不重复 = SUMMARIZECOLUMNS('多列重复'[年份], '多列重复'[姓名])

注:可以不是同一张表,但是必须有关系的多张表。

案例三:返回汇总表【分组求和;使用第134参数】

【新建表】

汇总表 = SUMMARIZECOLUMNS('分组求和'[年份], '分组求和'[姓名], "总分", SUM('分组求和'[成绩]))

案例四:返回带筛选功能的汇总表【第二参数】

汇总表筛选 = SUMMARIZECOLUMNS('分组求和'[年份], '分组求和'[姓名], FILTER('分组求和', '分组求和'[科目] = "数学"), "数学", SUM('分组求和'[成绩]))

-- 相当于把原表筛成数学后对其进行

注意:

SUMMARIZECOLUMNS只适合新建表,不能在度量值中使用。

如果需要在度量值中执行分组和新建列时,最可靠的方式是SUMMARIZE+ADDCOLUMNS

2.ADDMISSINGITEMS【就是一个开关】

语法:

ADDMISSINGITEMS([<展示列>, …], <汇总列>, [<分组列>, …], <筛选条件>)

展示列:需要展示出来的列;可缺省;可多个

汇总列:经过筛选处理之后的表

分组列:用来分组的列;可缺省;可多个

例如:

SUMMARIZE不显示"成绩"为空白的人员

-- 原表

-- 汇总表(不显示孙兴华)

ADDMISSINGITEMS+SUMMARIZE可以显示(这个组合与单独使用SUMMARIZE出来的效果是一样的)

【新建表】

汇总表2 = ADDMISSINGITEMS('分组求和'[年份], '分组求和'[姓名], SUMMARIZECOLUMNS('分组求和'[年份], '分组求和'[姓名], "总分", SUM('分组求和'[成绩])), '分组求和'[年份], '分组求和'[姓名])

第一参数:和SUMMARIZECLOLUMNS相同的分组列

第二参数:SUMMARIZECLOLUMNS表达式

第三参数:和SUMMARIZECLOLUMNS相同的分组列

套ADDMISSINGCOLUMNS开关的场景:想显示空值记录的时候

3.INTERSECT、EXCEPT、UNION

INTERSECT(A, B) - 交集

EXCEPT(A, B) - 差集

UNION(A, B) - 并集

【新建表】

刺杀且死亡名单 = INTERSECT('刺杀名单', '死亡名单')

刺杀未死亡名单 = EXCEPT('刺杀名单', '死亡名单')

刺杀名单和死亡名单并集 = UNION('刺杀名单', '死亡名单')

4.CROSSJOIN笛卡尔积

表1:

表2:

【新建表】

笛卡尔积 = CROSSJOIN('1', '2')

二十四. 查找匹配函数

1.CONTAINS【多条件查找】

CONTAINS为简单筛选提供了更好的性能,而CALCULATETABLE适用于复杂的筛选表达式。

【新建度量值】

是否购买过 = CONTAINS('', ''[日期], DATE(2020, 12, 2), ''[姓名], "李四")

-- CONTAINS返回的是布尔值

2.TREATAS【无关系情况下查找匹配】

TREATAS函数时无关系情况下执行查找匹配的最佳选择。

语法:

TREATAS(<table_expression>, <column>[,[column]…])

作用:把什么当做什么

解释:把一参当做二参的筛选器,通过一参筛选二参

注意:一参是唯一值的表

案例一:单列筛选(求各月份的销售目标)

【新建表】

日期表 = ADDCOLUMNS(

CALENDAR(DATE(2020,1,1),DATE(2021,12,31)),

"",YEAR([Date]),

"",MONTH([Date]),

"",WEEKNUM([Date]),

"年季度",YEAR([Date])&"Q"&ROUNDUP(MONTH([Date])/3,0),

"年月",YEAR([Date])*100+MONTH([Date]),

"年周",YEAR([Date])*100+WEEKNUM([Date]),

"星期几",WEEKDAY([Date])

)

"销售目标"表中没有详细日期,无法与"日期表"建立直接的关系。

现在想用日期表筛选销售目标表,比如用'日期表'.[月]筛选'销售目标'.[销售目标]。把日期表的[月]用作筛选条件(一参),而销售目标表的[月份]则是被一参筛选的列(二参)。

【新建度量值】

月度销售目标 = CALCULATE(SUM('销售目标'[销售目标]), TREATAS(VALUES('日期表'[]), '销售目标'[月份]))

矩阵表行上放日期表的[月],值上放[月销售目标]

案例二:多列筛选(求各年份月份的销售目标)

【新建度量值】

年月销售目标1 = CALCULATE(SUM('销售目标'[销售目标]), TREATAS(VALUES('日期表'[]), '销售目标'[年份]), TREATAS(VALUES('日期表'[]), '销售目标'[月份]))

矩阵表行上放日期表的[年],列上放日期表[月],值上放[年月销售目标1]

多条件筛选时,如果数据量比较大,考虑速度问题,可以使用SUMMARIZE进行优化

年月销售目标2 = CALCULATE(SUM('销售目标'[销售目标]), TREATAS(SUMMARIZE('日期表', '日期表'[], '日期表'[]), '销售目标'[年份], '销售目标'[月份]))

-- SUMMARIZE和SUMMARIZECOLUMNS的唯一区别就是,前者要先指明是哪个表,然后在指明分组的列,而后者直接指明是哪个表的哪个列;SUMMARAIZECOLUMNS不能写在度量值里,会报错

3.ROW函数【返回一个单行表,其中包含由DAX表达式指定的新列】

语法:

ROW(<Name>, <Expression>, [<Name>, <Expression>], […])

说人话:就是创建一张表

ROW("新列名", 创建这个新列用什么表达式)

案例:

【新建表】

测试表 = ROW("总销量", SUM('Row'[销售量]), "总金额", SUM('Row'[销售金额]))

4.综合案例分析:利用TREATAS函数自由切换坐标轴

(1)利用笛卡尔积做表

思路分析:

【新建表】

坐标轴 =

UNION(

    UNION(

        CROSSJOIN(ROW("坐标轴", "城市"), VALUES('案例'[城市])),

        CROSSJOIN(ROW("坐标轴", "产品"), VALUES('案例'[产品]))

    ),

    CROSSJOIN(ROW("坐标轴", "年份"), VALUES('案例'[年份]))

)

-- UNION一次只能连接2张表,所以要使用两次UNION

-- UNION用第一张表的列名作为合并表的列名,可以手工改一下列名(双击列名),更好理解

(2)第二个切片器

【新建表】

切换 = UNION(ROW("结果", "销量"), ROW("结果", "销售金额")

(3)把两个总度量值写出来

【新建度量值】

总销量 = SUM('案例'[销量])

总金额 = SUM('案例'[销售金额])

(4)分别写显示销量与显示销售金额的度量值

【新建度量值】

显示销量 = SWITCH(

    SELECTEDVALUE('坐标轴'[坐标轴]),

    "城市", CALCULATE('案例'[总销量], TREATAS(VALUES('坐标轴'[类别]), '案例'[城市])),

    "产品", CALCULATE('案例'[总销量], TREATAS(VALUES('坐标轴'[类别]), '案例'[产品])),

    "年份", CALCULATE('案例'[总销量], TREATAS(VALUES('坐标轴'[类别]), '案例'[年份]))

)

-- 当切片器单选的时候,如果选"城市",显示各城市销量;如果选"产品",显示各产品销量;如果选"年份",显示各年份销量

显示金额 = SWITCH(

    SELECTEDVALUE('坐标轴'[坐标轴]),

    "城市", CALCULATE('案例'[总金额], TREATAS(VALUES('坐标轴'[类别]), '案例'[城市])),

    "产品", CALCULATE('案例'[总金额], TREATAS(VALUES('坐标轴'[类别]), '案例'[产品])),

    "年份", CALCULATE('案例'[总金额], TREATAS(VALUES('坐标轴'[类别]), '案例'[年份]))

)

(5)最后把结果做出来

OK = SWITCH(SELECTEDVALUE('切换'[结果]), "销量", '案例'[显示销量], "销售金额", '案例'[显示金额])

切片器1字段上放'坐标轴'[坐标轴],切片器2字段上放'切换'[结果],簇状柱形图X轴放'坐标轴'[类别],Y轴放'案例'[OK]

5.VAR声明变量

接上节课案例:

显示金额和显示销售我们做了两个度量值,又做了一个OK的度量值。

用VAR一步搞定

【新建度量值】

度量值 =

VAR xiaoliang = SWITCH(

    SELECTEDVALUE('坐标轴'[坐标轴]),

    "城市", CALCULATE('案例'[总销量], TREATAS(VALUES('坐标轴'[类别]), '案例'[城市])),

    "产品", CALCULATE('案例'[总销量], TREATAS(VALUES('坐标轴'[类别]), '案例'[产品])),

    "年份", CALCULATE('案例'[总销量], TREATAS(VALUES('坐标轴'[类别]), '案例'[年份]))

)

VAR jine = SWITCH(

    SELECTEDVALUE('坐标轴'[坐标轴]),

    "城市", CALCULATE('案例'[总金额], TREATAS(VALUES('坐标轴'[类别]), '案例'[城市])),

    "产品", CALCULATE('案例'[总金额], TREATAS(VALUES('坐标轴'[类别]), '案例'[产品])),

    "年份", CALCULATE('案例'[总金额], TREATAS(VALUES('坐标轴'[类别]), '案例'[年份]))

)

RETURN SWITCH(SELECTEDVALUE('切换'[结果]), "销量", xiaoliang, "销售金额", jine)

簇状柱形图Y轴换成'案例'[度量值],效果和'案例'[OK]一致

除了可以定义度量值,还可以定义新建列:

【新建列】

评价 =

VAR zongfen = '案例2'[数学] + '案例2'[英语] + '案例2'[语文]

RETURN IF(zongfen >= 270, "优秀", "一般")

-- 评价三门科目总分

等同于:

评价 = IF('案例2'[数学] + '案例2'[英语] + '案例2'[语文] >= 270, "优秀", "一般")

【实战案例】模糊查找

【新建度量值】

查询类型 =

VAR a = VALUES('查询表'[类型])

VAR b = MAX('销售表'[类型])

RETURN

    IF(

        COUNTROWS(FILTER(a, SEARCH('查询表'[类型], b, 1, 0) > 0)) > 0,

        b,

        BLANK()

    )

-- MAX('销售表'[类型]):借助聚合函数返回[类型]的值,这里的作用单纯是为了将[类型]列进行聚合,否则无法在查询函数中使用,用MIN也可以

-- 通过IF语句进行判断,符合条件显示,否则显示为空;内部利用FILTER进行上下文传递,将原本没有联系的维度和事实表连接在一起

矩阵表值上放'查询表'[查询类型],行上放'销售表'[电影],切片器字段上放'查询表'[类型]

6.检查字符串是否被包含

FIND和SEARCH函数都可以查找指定字符串所在的位置,如果只需要检查字符串是否被包含,可以使用CONTAINSSTRING和CONTAINSSTRINGEXACT,它们只进行逻辑判断,计算效率更高。

(1) CONTAINSSTRING 支持通配符,不区分大小写

CONTAINSSTRING(<WITHINTEXT>, <FINDTEXT>)

列 = CONTAINSSTRING("跟着孙兴华学VBA", "孙?华")

如果一个文本字符串包含另一个文本字符串,则返回TRUE。

CONTAINSSTRING支持通配符,不区分大小写,可以执行模糊匹配,使用时注意它的参数顺序。

问号(?):问号匹配任何单个字符

星号(*):星号匹配任何字符序列

如果想找到的是问号或星号本身,请在字符前键入一个波浪号(~) --即转义字符

(2) CONTAINSSTRINGEXACT 不支持通配符,区分大小写

CONTAINSSTRING(<WITHINTEXT>, <FINDTEXT>)

列 = CONTAINSSTRING("跟着孙兴华学VBA", "孙兴华")

如果一个文本字符串包含另一个文本字符串,则返回TRUE。

CONTAINSSTRINGEXACT不支持通配符,区分大小写,使用时注意它的参数顺序。

二十五. 排名函数

1.RANKX排名

语法:

RANKX(<table>, <expression>, [<value>], [<order>], [<ties>])

第一参<table>:表,也可以是用函数生成的表

第二参<expression>:表达式,聚合表达式或写好的度量值

第三参<value>:值,可选,可以是个聚合表达式,也可以是直接的数值;当<value>省略时,用<expression>代替

第四参<order>:排序,ASC或DESC,升序或降序

第五参<ties>:排序方法,skip国际排序(下一名的排序等于之前所有排序的数量+1),dense中国式排序(只累加排序,不考虑数量)-- 看PowerQuery S01E11排名

【新建度量值】

总金额 = SUM('销售表'[销售金额])

排名 = RANKX(ALL('销售表'), '销售表'[总金额])

矩阵表行上放'销售表'[商品编码],值上放'销售表'[总金额]、'销售表'[排名]

两个问题:总计的排名列不应该显示、A007和A008的排名不应该显示

想要让总计不显示,通用方法:IF + HASONEVALUE

【新建度量值】

排名优化1 = IF(HASONEVALUE('销售表'[商品编码]), RANKX(ALL('销售表'), '销售表'[总金额]), BLANK())

矩阵表值上加上'销售表'[排名优化1]

去掉A007A008

AND(TRUE, TRUE)才返回TRUE

AND(TRUE, FALSE)就返回TRUE

【新建度量值】

排名优化2 = IF(AND(HASONEVALUE('销售表'[商品编码]), '销售表'[总金额] >0), RANKX(FILTER(ALL('销售表'), '销售表'[总金额] > 0), '销售表'[总金额], , DESC), BLANK())

矩阵表值上只放'销售表'[排名优化2]

ALL函数是绝对排名的用法,如果是相对排名,可以自行替换成ALLSELECTED

如果不输入第三参,第二参也是第三参,一旦输入第三参,结果显示的是第三参按照第二参排名的位置。

假如有一份普通中学学生成绩的分数,和一份重点中学成绩排名,向看看普通中学的学生在重点中学能排第几,这就是实际第三参的用途。

-- 第三参没有展开讲,需看官方文档

【进阶】RANKX进行明细级别的排名

【新建列】

单品销售排名 = RANKX(FILTER('案例2', '案例2'[品种] = EARLIER('案例2'[品种])), '案例2'[销售金额])

2.TOPN【返回满足条件的前N行记录】

RANKX适合计算明细的名次数据,TOPN则可以批量返回结果,从一张表中返回所有满足条件的前N行记录。

它的特点是返回的不是值,而是前N行的表。

语法:

TOPN(N, , [表达式], [顺序可选项])

N值:排名前N位

表:想要提取的表

[表达式]:用来排序的度量值或表达式

[顺序可选项]:排序方式,0/FALSE/DESC降序,1/TRUE/ASC升序

【新建表】

查询销售前2名的记录 = TOPN(2, 'TOPN', 'TOPN'[销售金额], DESC)

-- 求前2名的销售金额之和

2名的销售金额之和 = SUMX(TOPN(2, 'TOPN', 'TOPN'[销售金额], DESC), 'TOPN'[销售金额])

-- 因为新建列是行上下文,不具备筛选功能,可以建成度量值或套上CALCULATE,但是在此例中没有意义,所以就不套了

注意,当销售金额有重复值时,TOPN拿到的不一定是前两名,并列的也会算在里面占用名额。在实际分析中,通常不是配合SUMX使用,而是配合AVERAGEX使用计算平均值。

案例:

-- 计算销售量前3名共卖了多少

【新建度量值】

销售额 = SUM('TOPN'[销售金额])

【新建表】

测试表 = TOPN(3, ALL('TOPN'), 'TOPN'[销售额], DESC)

【新建度量值】

销售量前3名共卖了多少 = CALCULATE('TOPN'[销售额], TOPN(3, ALL('TOPN'), 'TOPN'[销售额], DESC)

卡片图字段放'TOPN'[销量表前3名共卖了多少]

-- 计算销售量前3名的店铺共卖了多少:找出销售额最高的3家店铺,然后把金额加在一起

【新建表】(把TOP3的店号取出来)

测试表2 = TOPN(3, ALL('TOPN'[店号]), 'TOPN'[销售额], DESC)

【新建度量值】(通过TOP3店号筛选'TOPN'表,从而计算TOP3店铺的总销售额)

销售量前3名的店铺共卖了多少 = CALCULATE('TOPN'[销售额], TOPN(3, ALL('TOPN'[店号]), 'TOPN'[销售额], DESC))

卡片图字段放'TOPN'[销售量前3名的店铺共卖了多少]

【新建度量值】

3名的店铺销售占比 = DIVIDE('TOPN'[销售量前3名的店铺共卖了多少], CALCULATE('TOPN'[销售额], ALL('TOPN'[店号])))

-- 这里ALL函数的参数也可以是'TOPN'表,效果是一样的,都是计算整张表的总销售额

卡片图字段放'TOPN'[前3名的店铺销售占比]

3.CONCATENATEX【将多个值连接到一起,以文本的形式输出】

语法:

CONCATENATEX(<Table>, <Expression>, [Delimiter], [OrderBy_Expression], [Order1], …)

第一参<Table>:用于表达式每行计值的表;第一参数必须是唯一值的表

第二参<Expression>:用于逐行计算的表达式

第三参[Delimiter]:连接表达式结果的连接符

第四参[OrderBy_Expression]:排序使用的表达式

第五参[Order1]:排序逻辑

案例一:

【新建度量值】

三部曲 = CONCATENATEX(VALUES('CONCATENATEX'[人物]), 'CONCATENATEX'[人物], "", 'CONCATENATEX'[人物], DESC)

矩阵表行上放'CONCATENATEX'[小说],值上放'CONCATENATEX'[三部曲]

-- 按人物姓名首字母降序排

案例二:对结果进行排序(查询每个人哪天买了东西)

【新建度量值】

度量值1 = CONCATENATEX(VALUES('流水'[购物日期]), FORMAT('流水'[购物日期], "yyyy/mm/dd"), "", '流水'[购物日期], ASC)

矩阵表行上放'花名册'[姓名],值上放'花名册'[度量值1]

等效表达式:

度量值1 = CONCATENATEX(RELATEDTABLE('流水'), FORMAT('流水'[购物日期], "yyyy/mm/dd"), "", '流水'[购物日期], ASC)

-- 花名册找流水表,一端找多端,用RELATEDTBALE引路人

案例三:CONCATENATEX综合案例

-- 原数据

Step1. 利用CONCATENATEX函数将多个值连接在一起

【新建度量值】

购买商品 = CONCATENATEX(VALUES('补充案例'[商品]), '补充案例'[商品], "")

Step2. 让总计栏显示为空(通用方法:IF + HASONEVALUE)

【修改度量值】

购买商品 = IF(HASONEVALUE('补充案例'[买家昵称]), CONCATENATEX(VALUES('补充案例'[商品]), '补充案例'[商品], ""))

矩阵表行上放'补充案例'[卖家昵称],值上放'补充案例'[购买商品]

Step3. 计算购买数量和金额

购买数量 = SUM('补充案例'[销售数量])

消费金额 = SUMX('补充案例', '补充案例'[单价] * '补充案例'[购买数量])

-- SUM函数的参数只能是物理列,不能是表达式;可以先在表中新建列计算乘积,再到度量值里SUM,但是数据量大的情况下耗费内存;最好的方法是直接在度量值里用SUMX,一步搞定计算表达式及求和

矩阵表值上加'补充案例'[购买数量]和'补充案例'[消费金额]

Step4. 计算客户等级

【新建度量值】

客户等级 = IF(HASONEVALUE('补充案例'[买家昵称]), SWITCH(

    TRUE(),

    '补充案例'[消费金额] >= 3000, "金牌客户",

    '补充案例'[消费金额] >= 1000, "银牌客户",

    "铜牌客户"

))

-- SWITCH函数第一参数为TRUE()的效果:返回条件判断列表中第一个为TRUE的结果

矩阵表值上加'补充案例'[客户等级]

二十六. 人工造表最终方案

ADDCOLUMNS 从指定的表开始添加列

SELECTCOLUMNS 从空表开始添加列

1.ADDCOLUMNS

语法:

ADDCOLUMNS(<>, <名称1>, <表达式1>, …) 返回具有DAX表达式指定的新列的表

【新建表】

日期表 = ADDCOLUMNS(

CALENDAR(DATE(2019,1,1),DATE(2021,12,31)),

"",YEAR([Date]),

"季度",ROUNDUP(MONTH([Date])/3, 0),

"",MONTH([Date]),

"",WEEKNUM([Date]),

"年季度",YEAR([Date])&"Q"&ROUNDUP(MONTH([Date])/3,0),

"年月",YEAR([Date])*100+MONTH([Date]),

"年周",YEAR([Date])*100+WEEKNUM([Date]),

"星期几",WEEKDAY([Date])

)

解析:

(1) CALENDAR(<开始日期>, <结束日期>) 创建一张开始日期和节数日期之间的日期表

(2) 季度

ROUNDUP(<数目>, <[NumberOfDigits]>) 从零开始,向上舍入数值

e.g.

ROUNDUP(1.88) 向上取整数,返回2

ROUNDUP(1.88, 1) 保留一位小数向上取,返回1.9

数学题:

1/3=0.3333,向上舍入保留0位小数点,就是1

2/3=0.6667,向上舍入保留0位小数点,就是1

4/3=1.3333,向上舍入保留0位小数点,就是2

案例:

向'表'添加两列,分别是各班级总分和平均分

【新建表】

2 = ADDCOLUMNS('', "总分", CALCULATE(SUM('数据'[分数])), "平均分", CALCULATE(AVERAGE('数据'[分数])))

-- 因为要筛选,所以要套CALCULATE,也可以写度量值

【修改表】筛选出平均分小于50的

2 = FILTER(ADDCOLUMNS('', "总分", CALCULATE(SUM('数据'[分数])), "平均分", CALCULATE(AVERAGE('数据'[分数]))), [平均分] < 50)

2.SELECTCOLUMNS

语法:

SELECTCOLUMNS(<>, <名称1>, <表达式1>, …) 返回具有从表中选择的列以及DAX表达式指定的新列的表

第1参<表>:从中选择列的表

第2参<名称>:要添加的新列的名称,可重复

第3参<表达式>:要添加的新列的表达式,可重复

案例:

【新建表】

3 = SELECTCOLUMNS('销售表',

    "销售日期", '销售表'[日期],

    "商品名称", RELATED('商品表'[名称]),

    "销售数量", '销售表'[销售量],

    "销售金额", '销售表'[销售量] * RELATED('商品表'[进价])

)

-- RELATED:销售表找商品表,多端找一端,使用RELATED引路人

二十七. 日期时间函数【智能函数】

27.1 计算累计值

计算累计有2类常用的时间智能函数:

DATESYTD为代表的返回日期值的表函数、以TOTALYTD为代表的返回标量值的函数

YTD:计算本年的年初至今

QTD:季初至今

MTD:月初至今

1.DATESYTD类【已淘汰】

语法:

DATESYTD(<Dates>, <[YearEndDate]>) 返回此年度中截至当前日期的一组日期

第1参数:日期格式的列或返回单列的表达式,通常使用日期表的日期列

第2参数:年截止日,日期字符串,忽略年

-- 以表中最大日期作为本年

原始表:

【新建表】

测试表 = DATESYTD(''[日期])

-- 原始表最大日期是2021年的,所以返回2021年的年初至今日期

测试表 = DATESQTD(''[日期])

测试表 = DATESMTD(''[日期])

总结:

返回的是一张表

(1) DATESYTD(年初至今)

根据日期数据决定,相当于把日期数据排序,找到最大的年,再求年至今。如果数据中最大的年是2021年,那就计算2021年;如果数据中最大的年是2030年,那就计算2023年

(2) DATESQTD(季初至今)

先找到最大年,再找最大月,确定最大月所在季度后,将这个时间表拿出来

(3) DATESMTD(月初至今)

先找到最大年,再找最大月,将这个时间表拿出来

案例:计算年初至今的销售量

【新建度量值】

总销售 = SUM(''[销售])

年初至今 = CALCULATE('测试表'[总销售], DATESYTD(''[日期]))

卡片图字段上放'表'[年初至今]

-- TOTALYTD类函数可以代替CALCULATE+DATESYTD这样的组合。

2.TOTALYTD类【推荐】

【修改度量值】

年初至今 = TOTALYTD('测试表'[总销售], ''[日期])

语法:

TOTALYTD(<表达式>, <日期列>, <[筛选器]>, <[截止日期]>)

第1参<表达式>:返回标量值的表达式

第2参<日期列>:包含日期的列

第3参<[筛选器]>:可选,应用于当前上下文的筛选器参数,可以使布尔表达式或表表达式;即先把表筛选完之后再去算YTD

第4参<[截止日期]>:带有日期的文本字符串,用于定义年末日期,默认值为12月31日

TOTALYTD:计算本年的年初至今

TOTALQTD:季初至今

TOTALMTD:月初至今

【新建度量值】

年初至今1 = TOTALYTD('测试表'[总销售], ''[日期], FILTER('', ''[销售] < 50))

年初至今2 = TOTALYTD('测试表'[总销售], ''[日期], FILTER('', ''[销售] < 50), "03/31")

-- 3.31定义为年末日期,则从4.1开始算作一年的开始

通常6月30日是财务年度的结束日期,每年的7月1日是财务年的开始日:

TOTALYTD([总销量], '表'[日期], "06-30")

27.2 同比与环比

同比率 = (本期 - 去年同期) / 去年同期 * 100%

环比率 = (本期 - 上期)  / 上期 * 100%

上期可以是上季度、上月、上周,甚至上一日

1.同比推荐:SAMEPERIODLASTYEAR【前一年】

语法:

SAMEPERIODLASTYEAR(<日期列>)

官方:返回当前筛选上下文中前一年的一组日期

说人话:在表中找到日期列最大的年、月、日,找到它的同比时间

原始表:

【新建表】测试

前一年 = SAMEPERIODLASTYEAR(''[日期])

-- 先确定好哪个是今年,然后再找到去年;时间区间相同,今年1.1~6.30对应去年1.1~6.30

【新建度量值】计算同比

总销售 = SUM(''[销售])

同比销售金额 = CALCULATE([总销售], SAMEPERIODLASTYEAR(''[日期]))

卡片图字段上放'表'[同比销售金额]

-- 结果:1+0+2+3+4+5 = 15

2.环比:DATEADD

语法:

DATEADD(<日期列>, <偏移量>, <偏移单位>)

第1参<日期列>:包含日期的列

第2参<偏移量>:一个整数,从日期列中添加或减去的时间间隔数

第3参<偏移单位>:偏移量使用的单位,DAY/MONTH/QUARTER/YEAR

-- 返回的是一张表

原始表:

【新建表】测试

返回的是一张表 = DATEADD('DATEADD'[日期], 0, YEAR)

返回的是一张表 = DATEADD('DATEADD'[日期], 1, YEAR)

返回的是一张表 = DATEADD('DATEADD'[日期], -1, YEAR)

 

【新建度量值】测试

总销售 = SUM('DATEADD'[销售])

上年 = CALCULATE([总销售], DATEADD('DATEADD'[日期], -1, YEAR)

矩阵表行上放'DATEADD'[日期],值上放'DATEADD'[总销售]、'DATEADD'[上年]

案例:

原始表:

【新建度量值】

总销售 = SUM('2'[销售])

上年 = CALCULATE('2'[总销售], DATEADD('2'[日期], -1, YEAR))

上月 = CALCULATE('2'[总销售], DATEADD('2'[日期], -1, MONTH))

上季 = CALCULATE('2'[总销售], DATEADD('2'[日期], -1, QUARTER))

矩阵表行上放'表2'[日期],值上放'表2'[上年]、'表2'[上月]、'表2'[上季]

-- 7月的上季销售就是上季度第1个月的销售,即4月的销售;同理,8月的上季销售就是上季度第2个月的销售,即5月的销售

【新建度量值】算环比

本月销售 = TOTALMTD('2'[总销售], '2'[日期])

上月销售 = TOTALMTD('2'[总销售], DATEADD('2'[日期], -1, MONTH))

卡片图字段上放'表2'[本月销售],卡片图字段上放'表2'[上月销售]

和原始表一致:

3.利用时间计算累积值:PARALLELPERIOD

区别:

1PARALLELPERIOD函数返回的是完整的时间范围,而DATEADD函数返回的结果是可以间断的

2PARALLELPERIOD函数针对的是一段范围的数据汇总DATEADD函数通常用来计算同比环比问题,针对的是某一个点

语法:

PARALLELPERIOD(<日期列>, <偏移量>, <偏移单位>)

第1参<日期列>:包含日期的列

第2参<偏移量>:一个整数,从日期列中添加或减去的时间间隔数

第3参<偏移单位>:偏移量使用的单位,DAY/MONTH/QUARTER/YEAR

【新建度量值】测试

总销售 = SUM('2'[销售])

DATEADD = CALCULATE('2'[总销售], DATEADD('2'[日期], -1, QUARTER))

PARALLELPERIOD = CALCULATE('2'[总销售], PARALLELPERIOD('2'[日期], -1, QUARTER))

矩阵表行上放'表2'[日期],值上放'表2'[DATEADD]、'表2'[PARALLELPERIOD]

-- '表2'[PARALLELPERIOD]返回的是上个季度销售的总和

案例:

【新建度量值】

本季销售 = CALCULATE('2'[总销售], PARALLELPERIOD('2'[日期], 0, QUARTER))

上季销售 = CALCULATE('2'[总销售], PARALLELPERIOD('2'[日期], -1, QUARTER))

切片器字段上放'表2'[日期];折线图X轴上放'表2'[日期],Y轴上放'表2'[本季销售]、'表2'[上季销售]

-- 一般用于图表中,而不是计算环比值

27.3 计算移动总计

1.DATESINPERIOD

语法:

DATESINPERIOD(<日期列>, <起始日期>, <偏移量>, <偏移单位>)

返回给定区间中的所有日期组成的单列形式的表。

第1参<日期列>:包含日期的列

第2参<起始日期>:日期表达式

第2参<偏移量>:一个整数,从日期列中添加或减去的时间间隔数

第3参<偏移单位>:偏移量使用的单位,DAY/MONTH/QUARTER/YEAR

案例1:统计数据表中最后一天倒推最近12个月的销售额

原始表:

【新建表】测试

测试表 = DATESINPERIOD('3'[日期], MAX('3'[日期]), -1, YEAR)

【新建度量值】

测试 = CALCULATE(SUM('3'[销售]), DATESINPERIOD('3'[日期], MAX('3'[日期]), -1, YEAR))

卡片图字段上放'表3'[测试]

案例2:求最近30天的移动平均

原始表:

【新建表】测试

测试表 = DATESINPERIOD('4'[日期], MAX('4'[日期]), -30, DAY)

【新建度量值】

移动平均 = CALCULATE(SUM('4'[销量]), DATESINPERIOD('4'[日期], MAX('4'[日期]), -30, DAY)) / 30

卡片图字段上放'表3'[移动平均]

案例3:从上月算起,过去的3个月的日期

【新建表】

= DATESINPERIOD('4'[日期], EOMONTH(MAX('4'[日期]), -1), -3, MONTH)

-- EOMONTH函数用于平移指定月份(笔记19.03)

补充拓展知识1LASTDATEMAX的区别

LASTDATE返回的是一个表,MAX返回的是一个值。

在这里,使用MAX和LASTDATE都可以,等效表达式:

测试表 = DATESINPERIOD('4'[日期], LASTDATE('4'[日期]), -30, DAY)

但在有的情况下,这两个函数是有区分的,因为它们的返回值类型不同:

CALCULATE([度量值], LASTDATE('某张表'[日期列]))

CALCULATE([度量值], FILTER('某张表', '某张表'[日期列] = MAX('某张表'[日期列])))

当用于CALCULATECALCULATETABLE筛选器时,习惯用LASTDATEFIRSTDATE而不是MAXMIN

补充拓展知识2:动态日期表

【新建表】

日期表 = ADDCOLUMNS(

CALENDAR(FIRSTDATE('4'[日期]),LASTDATE('4'[日期])),

"",YEAR([Date]),

"季度",ROUNDUP(MONTH([Date])/3, 0),

"",MONTH([Date]),

"",WEEKNUM([Date]),

"年季度",YEAR([Date])&"Q"&ROUNDUP(MONTH([Date])/3,0),

"年月",YEAR([Date])*100+MONTH([Date]),

"年周",YEAR([Date])*100+WEEKNUM([Date]),

"星期几",WEEKDAY([Date])

)

-- 使用FIRSTDATE和LASTDATE函数自动生成数据表的日期表,而无需手动填入日期

2.ENDOFMONTHSTARTOFMONTH

语法:

ENDOFMONTH(<日期列>) 返回当月最后一天

STARTOFMONTH(<日期列>) 返回当月第一天

季度:

ENDOFQUARTER(<日期列>) 返回当季度最后一天

STARTOFQUARTER(<日期列>) 返回当季度第一天

年:

ENDOFYEAR(<日期列>, <[年度截止日期]>)

返回当年最后一天;<[年度截止日期]>:包含日期的文本字符串,用于定义年末日期,默认值为1231

STARTOFYEAR(<日期列>, <[年度截止日期]>)

返回当年第一天;<[年度截止日期]>:包含日期的文本字符串,用于定义年末日期,默认值为1231

【新建度量值】

每月最后3天销量 = CALCULATE(SUM('4'[销量]), DATESINPERIOD('4'[日期], ENDOFMONTH('4'[日期]), -3, DAY))

矩阵表行上放'表4'[日期]层级的月份(都是2020年的),值上放'表4'[每月最后3天销量]

每月前3天销量 = CALCULATE(SUM('4'[销量]), DATESINPERIOD('4'[日期], STARTOFMONTH('4'[日期]), -3, DAY))

进阶:返回当前上下文中最后一个日期或第一个日期

【新建表】

ENDOFMONTH('表4'[日期])    返回当前上下文中最后一个日期,类似MAX或LASTDATE函数

STARTDOFMONTH('表4'[日期])    返回当前上下文中第一个日期,类似MIN或FIRSTDATE函数

3.DATESBETWEEN区间日期

语法:

DATEDBETWEEN(''[日期], 开始日期, 结束日期)    返回两个给定日期之间的日期

【新建表】测试

测试表 = DATESBETWEEN('4'[日期], DATE(2020, 1, 1), DATE(2020, 1, 2))

注意,如果开始日期大于结束日期,结果为空。

【新建度量值】

区间销量 = CALCULATE(SUM('4'[销量]), DATESBETWEEN('4'[日期], DATE(2020, 1, 1), DATE(2020, 1, 2)))

卡片图字段上放'表4'[区间销量]

27.4 NEXT系列函数

1.NEXT系列函数【下一个】

表函数:

NEXTDAY【下一天】、NEXTMONTH【下一月】、NEXTDAY【下一季】、NEXTDAY【下一年】

例如:

DATESBETWEEN('表'[日期], DATE(2020, 1, 1), DATE(2020, 3, 10))

返回2020/1/1至2020/3/10这个期间的日期,如果在最外层套上NEXTDAY,就得到了2020/3/11这个日期的表。

案例:NEXTDAY实现错位值

原始表:

【新建度量值】

NEXTDAY = CALCULATE(SUM(NEXT[销售金额]), NEXTDAY('NEXT'[日期]))

矩阵表行上放'NEXT'[日期],值上放'NEXT'[销售金额]、'NEXT'[NEXTDAY]

例如:

DATESBETWEEN('表'[日期], DATE(2020, 1, 1), DATE(2020, 3, 10))

返回2020/1/1至2020/3/10这个期间的日期,如果在最外层套上NEXTMONTH,就得到了2020/4/1至2020/4/30这个日期的表。

案例:NEXTMONTH实现下个月销售的总计

【新建度量值】

NEXTMONTH = CALCULATE(SUM(NEXT[销售金额]), NEXTMONTH('NEXT'[日期]))

矩阵表值上加'NEXT'[NEXTMONTH]

2.PREVIOUS系列函数【上一个】

表函数:

PREVIOUSDAY【上一天】

PREVIOUSMONTH【上一月】

PREVIOUSDAY【上一季】

PREVIOUSDAY【上一年】

27.5 OPENINGBALANCE系列【期初库存】

值函数:

OPENINGBALANCEMONTH函数

OPENINGBALANCEQUARTER函数

OPENINGBALANCEYEAR函数

用途:计算月/季度/年的期初库存

注意,所谓月初库存就是上月底最后一天的库存。

语法:

OPENINGBALANCE函数(<表达式>, <日期>, <[筛选器]>)

案例:

原始表:

【新建度量值】

月初库存 = OPENINGBALANCEMONTH(SUM('期初'[库存]), '期初'[日期])

矩阵表行上放'期初'[日期],值上放'期初'[月初库存]

和原始表一致:

二十八. 筛选器函数

“筛选”函数,其本身不属于表函数,也不属于值函数,仅作为CALCULATE函数的调节器使用。

我们之前接触的函数,要么是返回表,要么是返回值。

28.1 REMOVEFILTERS【不推荐】

REMOVEFILTERS:移除筛选

-- 和ALL函数功能一样,但是ALL函数可以用来返回一张表,也可以放到筛选器里;而REMOVEFILTER只能放到CALCULATE的筛选器里,它是“筛选”函数。

REMOVEFILTERS函数与ALL函数特性相同(【注意ALL函数特性】):

(1)ALL参数为表时,忽略所有的筛选条件,无论是该图表内还是外部切片器

(2)当ALL参数为列时,忽略该列筛选,其他图表字段或外部筛选对其产生作用

(3)ALL函数在引用列的时候必须与矩阵的行和列在同一张表

案例:

原始表:

【新建度量值】

总销售 = SUM('REMOVEFILTERS'[销售金额])

ALL = CALCULATE('REMOVEFILTERS'[总销售], ALL('REMOVEFILTERS'))

REMOVEFILTERS = CALCULATE('REMOVEFILTERS'[总销售], REMOVEFILTERS('REMOVEFILTERS'))

矩阵表行上放'REMOVEFILTERS'[日期],值上放'REMOVEFILTERS'[总销量]、'REMOVEFILTERS'[ALL]、'REOVEFILTERS'[REMOVEFILTERS]

度量值 = CALCULATE('REMOVEFILTERS'[总销售], REMOVEFILTERS('REMOVEFILTERS'[日期]))

推荐直接使用ALL函数

28.2 KEEPFILTERS追加筛选】

案例:

原始表:

【新建度量值】

总金额 = SUM('KEEPFILTERS'[销售金额])

A商品销售 = CALCULATE('KEEPFILTERS'[总金额], 'KEEPFILTERS'[商品] = "A")

矩阵表行上放'KEEPFILTERS'[日期],值上放'KEEPFILTERS'[总金额]、'KEEPFILTERS'[A商品销售]

矩阵表行上换成'KEEPFILTERS'[产品]

-- 'KEEPFILTERS'[A商品销售]显示异常,B和C行不应该显示值;原因是表达式并没有告诉图表可以用商品进行筛选(没懂)

解决方法:

(1)【修改度量值】

A商品销售 = CALCULATE('KEEPFILTERS'[总金额], 'KEEPFILTERS'[商品] = "A", VALUES('KEEPFILTERS'[商品]))

-- 实现用商品进行筛选

(2)【新建度量值】

A商品销售KEEP = CALCULATE('KEEPFILTERS'[总金额], KEEPFILTERS('KEEPFILTERS'[商品] = "A"))

解析:

总结:

KEEPFILTERS是表达式内部筛选条件与外部筛选(比如图表中的字段筛选)取交集,在这里就是[商品] = "A"和矩阵表行上放[商品](度量值自动根据行筛选)两个筛选取交集;

CALCULATE自带的筛选器是表达式内部筛选条件取交集,在这里就是[商品] = "A"和VALUES([商品])两个筛选条件取交集,不涉及外部

28.3 CROSSFILTERS【交叉筛选】

语法:

CROSSFILTER(多端固定列名, 一端固定列名, 方向)

-- 必须是固定列名,不能是表达式生成的

方向:

Oneway - 单向筛选(一端只能筛选多端,多端只能向一端索取数据)

Both - 双向筛选(两张表之间既可以筛选,也可以索取)

None - 无交叉筛选

功能一:改变筛选方向

-- 一端可以筛选多端,多端可以向一端索取数据

现在要实现多端筛选一端(通过销售表筛选出商品表中的商品数量):

【新建度量值】

商品数量 = COUNTROWS(RELATEDTABLE('商品表'))

矩阵表行上放'销售表'[商品编码],值上放'商品表'[商品数量]

-- 显示错误,商品表中每个商品应该只有1个

 

改变方向 = CALCULATE('商品表'[商品数量], CROSSFILTER('销售表'[商品编码], '商品表'[商品编码], Both))

-- CROSSFILTER函数的一参和二参是用来告诉表达式两张表是通过什么字段连接的

-- Both实现双向筛选,从而使销售表可以筛选商品表

矩阵值上加'商品表'[改变方向]

-- 此例没有实际意义,只是演示CROSSFILTER可以改变筛选方向

功能二:使用模型关系筛选时,数据量过大会导致模型运载变慢,此时可以使用CROSSFILTER函数进行优化

【新建度量值】

销售表数量 = COUNTROWS('销售表')

矩阵表行上放'销售表'[商品编码],值上放'商品表'[销售表数量]

【新建度量值】

改变连接方向后 = CALCULATE('商品表'[销售表数量], CROSSFILTER('销售表'[商品编码], '商品表'[商品编码], OneWay))

矩阵表值上加'销售表'[改变连接方向后]

-- 结果和直接计算是一致的,但是数据量大时,速度比直接计算快很多

注意事项:

1、如果模型关系是一对一的情况,使用ONEWAY和BOTH没区别

2、如果多端列和一端列位置反了,函数本身会自我修正

3、此函数只能在接受筛选器作为参数的函数中使用

目前涉及的有CALCULATE、CALCULATETABLE、TOTALYTD、TOTALQTD、TOTALMTD,其他没有讲

4、CROSSFILTER函数会覆盖任何现有筛选关系

5、如果两个参数没有任何连接关系,那么返回结果会报错

6、如果使用多个CROSSFILTER,最内层的会覆盖外面的

28.4 USERELATIONSHIP

用途:

1、用来激活指定的关系

2、适用于做关联分析

计算机生成了可选文字: USERELATIONSHIp(COlumnNamel, ColumnName2)  指 定 要 在 簋 DAX 表 达 鯊 中 甲 的 现 有 关 。 过 龕 名 个 作 为 卢 的 列 定 义  该 茨 亭 为 参 丨

案例一:

处理订单数量与收货数量

原始表:

计算机生成了可选文字: 订 单 日 期 以  2020 年 7, § , 曰  2020 年 冫 月 , 曰  2020 年 冫 , § , 曰  2020 年 冫 , § , 曰  2020 年 冫 月 , 曰  2020 年 冫 , § , 曰  2020 年 7, § 2 曰  收 货 日 期 商 品 名 称 以 售 星 -  2020 年 7, § 5 三  2020 年 7, § 8 三  2020 年 7, § 了 三  2020 年 7, § 5 曰  2020 年 7, § 9 曰  手 , 1  手 机  手 机  手 机  平 板

【新建表】动态日期表

日期表 = ADDCOLUMNS(

    CALENDAR(FIRSTDATE('某宝'[订单日期]), LASTDATE('某宝'[收货日期])),

    "", YEAR([Date]),

    "季度", QUARTER([Date]),

    "", MONTH([Date]),

    "", WEEKNUM([Date]),

    "年季度", YEAR([Date]) & "Q" & QUARTER([Date]),

    "年月", YEAR([Date]) * 100 + MONTH([Date]),

    "年周", YEAR([Date]) * 100 + WEEKNUM([Date]),

    "星期几", WEEKDAY([Date])

)

【模型视图创建连接】

'日期表'[Date]分别连'某宝'[订单日期]、'某宝'[收货日期]

计算机生成了可选文字: 日 “  鼕 宝  乏 月  二 0  订 E 期  , 品 名 称  耋 E 期

-- [订单日期]为主,是实线;

-- [收货日期]为辅,是虚线,为虚拟关系(不可用的关系)

【新建度量值】

下单数量 = SUM('某宝'[销售数量])

送达数量 = CALCULATE('某宝'[下单数量], USERELATIONSHIP('某宝'[收货日期], '日期表'[Date]))

-- 使用USERELATIONSHIP函数让'某宝'[收货日期]和'日期表'[Date]建立真的连接关系,这样就可以作为筛选条件,筛选出已经送达的日期

矩阵表行上放'日期表'[月],值上放'某宝'[下单数量]、'某宝'[送达数量]

计算机生成了可选文字: 月  总 计  下 数 呈 送 达 数

-- 14个已送达,11个未送达

筛选器[月]显示条件改为“不为空”-> 应用筛选器,可隐藏未送达的

计算机生成了可选文字: 不 力 空  选 型 0  高 級 笮  丘 亍 匾 力 以 下 内 春 項  不 力 巨  且 0  亡 辛 三 丘 器

计算机生成了可选文字: 月  下 邕 量 量

案例二:

-- 目的:创建两个维度(e.g.2个[名称])的切片器,使两者都可以对事实表('圣斗士')进行筛选且互不影响;图表左侧显示切片器1的结果,右侧显示切片器2的结果

-- 目标效果:

计算机生成了可选文字: 布 罗 迪  呵 , 迪 巴  1 艾 奥 里 亚  艾 俄 洛 斯  , 迪 斯 马 斯 克  左 项 目 右  河 魯 迪 巴 名 称 艾 俄 洛 斯  20 . 00 年 龄 14 . 00  工  名 称  阿 布 罗 迪  匚 迪 巴  艾 里 亞  艾 俄 洛 斯  . 1 迪 斯 马 斯 “

原始表:

计算机生成了可选文字: 名 称 以 年 龄 以 身 高  河 魯 逵 巴  戳 加  : 自 斯 马 斯 克  沙 i 〔  艾 俄 斯  河 布 罗 逵  2  重  囗  75  以 0  以 丆  以 2  以 5  58  70  70  以 4  以 5  以 3  75  72  - 生 日 囗  4 三 冫 了  4 三 959  4 三 9 以 ,  44 竄  44059  40 §  44 , 24  44 贬 4  4 嫠  44 5  4 三 842  4 三 858  4 三  . 血 型 以  AB  0  0  0

【新建表】

-- 为了在切片器中使用

名称1 = VALUES('圣斗士'[名称])

名称2 = VALUES('圣斗士'[名称])

计算机生成了可选文字: 名 称 以  河 魯 逵 巴  戳 加  : 自 斯 马 斯 荒  艾 俄 斯  河 布 罗 逵

【模型视图创建连接】

-- 如果用[名称1]'名称'和'名称2'[名称]都分别直接去连接'圣斗士'[名称],那么2个切片器的筛选结果会互相影响

计算机生成了可选文字: 同 名 称 1  名 称  圣 斗 士  名 称  , 重  同 名 称 2  名 称

将'名称2'和'圣斗士'之间的连线改为虚线(使关系不可用):右击连线 -> 属性 -> 取消勾选“使此关系可用” -> 确定

计算机生成了可选文字: 此 亭 可 用  设 引 用 亮 整 性  交 叉 篪 选 器 方 向  在 两 个 方 向 上 用 妄 全 篪 选 器

计算机生成了可选文字: 同 名 称 1  名 称  圣 斗 士  名 称  , 重  同 名 称 2  名 称

【新建度量值】

总年龄A = SUM('圣斗士'[年龄])

总年龄B = CALCULATE('圣斗士'[总年龄A], ALL('名称1'[名称]), USERELATIONSHIP('圣斗士'[名称], '名称2'[名称]))

-- ALL('名称1'[名称]):在使用'名称2'做筛选时,不希望'名称1'的筛选对计算产生影响

-- SUM仅是示例使用,在此例[年龄]字段上中不具备意义,在实际使用中多会使用,比如计算销售额累计等

切片器1字段上放'名称1'[名称];矩阵表行上放'圣斗士'[名称],值上放'圣斗士'[总年龄A]、'圣斗士'[总年龄B];切片器2字段上放'名称2'[名称]

计算机生成了可选文字: 申 昌  囗 阿 布 逵  囗 阿 魯 逵 巴  囗 艾 俄 刍 斯  囗 迪 斯 马 斯 克  囗 卡 妙  囗 米 以  囗 養  囗 撒  囗 沙 加  囗 修 以  名 称 , 乞 年 齡  艾 舅 圭 江  艾 , 斯  总 计  , 乞 年 齡 B  囗 阿 布 逵  囗 阿 魯 逵 巴  囗 艾 三 圭 亚  艾 俄 刍 斯  囗 迪 斯 马 斯 克  囗 卡 妙  囗 米 以  囗 養  囗 撒  囗 沙 加  囗 修 以

-- 虽然能实现独立筛选,但不是目标效果

【新建表】这里手工建了

主页- > 输入数据 -> 输入行列信息 -> 加载

计算机生成了可选文字: 创 建 表  顶 目  名 称

计算机生成了可选文字: 号 以 [  , 名 称

【新建度量值】

左 =

VAR A = SELECTEDVALUE(''[序号])

VAR B =

    SWITCH(

        TRUE(),

        A = 1, SELECTEDVALUE('名称1'[名称]),

        A = 2, '圣斗'[总年龄A]

    )

RETURN

    B

右 =

VAR A = SELECTEDVALUE(''[序号])

VAR B =

    SWITCH(

        TRUE(),

        A = 1, SELECTEDVALUE('名称2'[名称]),

        A = 2, '圣斗士'[总年龄B]

    )

RETURN

    B

-- 通用模板,以后遇到文本显示用SELECTEDVALUE,遇到数值计算用度量值或SUM等,添加其他字段显示就换行继续A = 3…

将报表视图中的矩阵表换成表,可以调整字段位置;表的列上先后依次放'圣斗士'[左]、'表'[项目]、'圣斗士'[右];最终实现效果:

计算机生成了可选文字: 申 昌  名 称  囗 阿 布  囗 阿 魯 逵 巴  囗 艾 俄 刍 斯  囗 迪 斯 马 斯 克  囗 卡 妙  囗 米 以  囗 養  囗 撒  囗 沙 加  囗 修 以  顶 右  艾 舅 圭 名 称 艾  20m 齡  14 . 00  名 称  囗 阿 布  囗 阿 魯 逵 巴  囗 艾 三 圭 亚  艾 俄 刍 斯  囗 迪 斯 马 斯 克  囗 卡 妙  囗 米 以  囗 養  囗 撒  囗 沙 加  囗 修 以

二十九. 中文排序

案例1

原表:

计算机生成了可选文字: 季 节

报表视图矩阵表行上放[季节],值上放[销量]

计算机生成了可选文字: 季 节 销 量  春  荩  秋  夏  总 计 1  10  80  50  30

-- 季节不是按照春夏秋冬排序的,而是按照拼音首字母

右键表 -> 编辑查询 -> 添加列 -> 索引列 -> 从1 -> 关闭并应用

计算机生成了可选文字: , 〕 2 ]  . 以 量

表格视图选中季节列 -> 列工具 -> 按列排序 -> 索引

计算机生成了可选文字: 文 件  0 名 称  主 页  亨 巧  助  表 工 R  列 工 輿  不 ; 匚 总  , 聹  日 嵋 爿 千 分 戔  季 节  , 文  季 节

回到报表视图

计算机生成了可选文字: 季 节 销 量  春  夏  秋  总 计 1  10  30  50  80

-- 已按照春夏秋冬排序

案例2

原表:

-- 不是按照目标顺序排好序的

计算机生成了可选文字:

报表视图矩阵表行上放'表2'[月份],值上放'表2'[销量]

计算机生成了可选文字: 月 份 销 量  六 月  三 月  四 月  石 月  一 月  总 计  5  1 1  14  18  52

主页 -> 输入数据 -> 根据排序要求创建月份表

计算机生成了可选文字: 创 建 表  目 份

查看模型视图

-- 已通过月份自动连线

计算机生成了可选文字: : 1

表格视图月份表选中月份列 -> 列工具 -> 按列排序 -> 索引

计算机生成了可选文字: 文 件  0 名 称  主 页  片 綸  助  表 工 以  列 工 輿  不 ; 匚 总  列 序  日 爿 千  索 引  , 文  巾 | : 以 豢 引 回

-- 因为两张表的月份存在连接关系,月份表按照索引排序,在表2也会生效

报表视图矩阵表行上换成'月份表'[月份]

计算机生成了可选文字: 月 份 肖  一 月  18  二 月  3  三 月  1 1  四 月  14  石 月  1  六 月  5  总 计  52

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Power-BI是一款(BI)商业智能软件,是珠海奥威软件科技有限公司自主研发的软件产品,全称是:Power-BI决策分析系统。 课程简介 本课程在《Power BI 数据分析快速上手》基础上结合大量的实例,深入讲解PowerBI中看似难懂的各种概念、操作, 并结合行业中的典型案例贯穿了从初级的数据透视工具、数据透视选项、数据透视的刷新、数据透视中的排序,到中级的动 态数据透视的创建、数据透视函数 GETPIVOTDATA 的使用、在数据透视中执行计算项、 可视化透视切片器等技能点,再到高级部分的使用 SQL 语句导入外部数据源创建透视、使用 Microsoft Query创建透视PowerPivot 与数据透视、数据透视图,以及最终的一页纸Dashboard 报告呈现, 都进行了详细的讲解。 本课程适合想提高 Power BI 的数据分析人员,特别是经常需要整理大量数据的相关人员。 课程目录 第1章:【Power BI 数据分析快速上手】Power BI概述、Power Map、Power Query初识 1. Power BI简介 2.Power BI组成部分 3.Power BI的DWT 4.Power BI的版权及费用 5.Power BI的安装及演示 6.Power BI四大护法 7.Power Map之静态地图 8.Power Map之动态地图 9.Power View之功能加载 10.Power View之高交互式可视化报使用 11.Power Query之花样数据导入 12.Power Query之数据合并(横向合并) 13.Power Query之数据合并(纵向合并) 14.Power Query之M函数 第2章:【Power BI 数据分析快速上手】Power BIPower Pivot插件详解 15.Power Pivot之数据导入 16.Power Pivot之层次结构创建 17.Power Pivot之创建KPI 18.Power Pivot之DAX函数(一) 19.Power Pivot之DAX函数(二) 20.Power Pivot之多维数据模型的创建 第3章:【Power BI 数据分析快速上手】综合案例:Power BI之大气质量数据分析 21.案例分析_大气质量(城市信息准备工作) 22.大气质量(导入大气质量文件夹数据) 23.大气质量(处理数据) 24.大气质量(Power View界面) 25.大气质量(基于Power View界面)制作仪板 26.大气质量(切片器样式处理) 27.大气质量(控件绑定) 28.大气质量(组合图实现) 29.大气质量(完成值联动) 30.大气质量(气泡地图制作) 第4章:Power BI Desktop 可视化应用实战 31.概念 32.运作方式 33.安装并运行 34.三种视图 35.查询编辑器 36.连接并调整数据 37.合并数据 38.创建图 第5章:Power BI 实战:财务指标-杜邦分析仪 39.财务杜邦分析仪的概念 40.财务杜邦分析仪制作(1) 41.财务杜邦分析仪制作(2) 42.财务杜邦分析仪制作(3) 43.财务杜邦分析仪制作(4) 44.财务杜邦分析制作仪(5) 第6章:Power BI 实战:销售运营管理数据分析 45.销售漏斗关系 46.搭建多维数据模型 47.洞察风险 48.故事序章 49.故事展开 50.故事高潮 51.故事尾声 52.P0WER QUERY数据处理(1) 53.P0WER QUERY数据处理(2) 54. P0WER QUERY数据处理(3) 55.P0WER PIVOT数据处理(1) 56.P0WER PIVOT数据处理(2) 57.P0WER PIVOT数据处理(3) 58.作业

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值