欢迎光临散文网 会员登陆 & 注册

Power BI之DAX神功:第3卷第2回 处理父子层级结构

2021-11-27 17:25 作者:孙兴华zz  | 我要投稿

声明:父子层级结构难点不在于DAX函数,在于表格的数据清洗,洗不出来就很难做出来。99%的情况下是不需要使用度量值生成父子层级结构的。直接在矩阵上用鼠标拖拽就可以满足大部分需求,只有精益求精以及特殊需求才会用到。

一、理解层级结构

最常见的层级结构图

不同的表格会有不同的深度,从单位到家庭,都有它自己的层级,数量均不相同。例如:左图有3个层级,右图有2个层级。我们以左图为例,做出如下表格:

// 爸爸和叔叔的上一级是爷爷,小明和小红上一级是爸爸,叔叔还没有孩子

二、制作层级序号

众所周知,PowerBI中有DAX和M两种语言,M函数负责数据清洗,DAX负责建模分析。而这件事情,就应该在导入数据时先进入PowerBI中的PowerQuery模块进行数据清洗。

视频名称是: 《孙兴华 PowerQuery M函数》全107集

https://www.bilibili.com/video/BV1oa4y1j75e

附送的M函数大全

现在我们使用模拟数据:为什么说它是模拟数据,因为真实数据肯定有大类编码、中类编码、商品编码等。

模拟数据表

我们想将模拟数据表标注层级关系,如下图所示:将原表变成目标表

PowerQuery M函数  代码如下:方法不唯一

Ps: 这里只是举例,不同的表格有不同的处理方法,而且方法有很多种。如果你没有学过我讲的PowerQuery课程,不易理解上面的代码。建议系统学习。

三、PATH函数

2021年11月2日我在《Power BI DAX 论数据清洗的重要性》视频中首次使用

https://www.bilibili.com/video/BV13R4y1E774?spm_id_from=333.999.0.0

语法:PATH ( <当前行序号>, <父级序号> )    作用:返回路径

表名:Sheet3

【新建列】路径 = PATH('Sheet3'[序号],Sheet3[父级])

就个函数就好比,有一个文件:孙兴华.txt  我想知道文件的绝对路径:

C:\免费讲课\喜欢nueco\酷爱dbykt\孙兴华.txt

解读:

第1层:C盘根目录

第2层:文件夹:免费讲课

第3层:文件夹:喜欢nueco

第4层:文件夹:酷爱dbykt

第5层:文件:孙兴华.txt

四、PATHITEM函数

语法:PATHITEM ( 路径, 位置, [返回类型]  // 从左向右

语法:PATHITEMREVERSE ( 路径, 位置, [返回类型])     // 从

例如:  PATHITEM ( "1|3|5", 3)   // 返回:5

例如:  PATHITEMREVERSE ( "1|3|5", 3)   // 返回:1

常用返回类型:

整数 (Integer)、十进制数 (Float)、货币 (Currency)、日期 (DateTime)、布尔值 (TRUE/FALSE)、文本 (String)

【新建列】第1级 = LOOKUPVALUE('Sheet3'[名称],Sheet3[序号],PATHITEM('Sheet3'[路径],1,INTEGER)

【新建列】第2级 = LOOKUPVALUE('Sheet3'[名称],Sheet3[序号],PATHITEM('Sheet3'[路径],2,INTEGER)

【新建列】第3级 = LOOKUPVALUE('Sheet3'[名称],Sheet3[序号],PATHITEM('Sheet3'[路径],3,INTEGER)

//《火力全开》第2课 重点讲了LOOKUPVALUE

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

如果只有3列,你就按上面的方法做就好了,如果有100列,你要新建100列吗?我建议,将数据复制到Excel中使用PowerQuery分成N列后再回到PowerBI中

注意:不能从PowerBI进入PowerQuery因为路径这一列是你在DAX中新建的列,PowerBI中的PQ不识别。以下代码可以满足不同需求使用

Power Query M函数:不填充

PowerQuery M函数 :填充

友情提示:如果没有看过我的PowerQuery 107集合集,很难看懂M函数的代码

五、PATHLENGTH 函数

语法:PATHLENGTH ( 路径)     返回:路径有几层

六、PATHCONTAINS ( 路径, 查找项目 )

七、我们使用真实案例

商品表
表名:销售表

【1】我们将商品表处理成目标表(带有本级序号和父级序号)

PowerQuery M函数代码如下:

【2】处理销售表,让销售表匹配商品表中的序号

实现商品表序号是主键,销售表序号是外键

商品表与销售表做合并查询,实现下面的样子:

将序号V过来以后的销售表

【3】建立关系(一对多关系)

现在可以实现连线关系了

【4】对商品表新建列

函数我们在上面都介绍过了

【新建列】路径 = PATH('商品表'[序号],'商品表'[父级序号])

【新建列】第1级 = LOOKUPVALUE('商品表'[商品名称],'商品表'[序号],PATHITEM('商品表'[路径],1,INTEGER))

【新建列】第2级 = LOOKUPVALUE('商品表'[商品名称],'商品表'[序号],PATHITEM('商品表'[路径],2,INTEGER))

【新建列】第3级 = LOOKUPVALUE('商品表'[商品名称],'商品表'[序号],PATHITEM('商品表'[路径],3,INTEGER))

 友情提示:序号和父级序号数据类型必需是整数

如果你看着第2级和第3级为空不舒服,可以通过公式补全他。

用DAX函数处理方法,修改第2级和第3级新建列公式:

有两个思路任选其一:

思路1:if(PATHITEM(路径,2)=Blank(),第1级,第2级)

// 如果路径第2层是空的,就返回第1级,否则返回第2级

思路2:if(PATHLENGTH(路径)=1,第1级,第2级)

// 如果路径的层级是1,就返回第1级,否则返回第2级

我们以学习为目的,将2个思路分别应用于第2级和第3级,效果相同,你任选其一

【新建列】第2级 = if(PATHITEM([路径],2)=Blank(),'商品表'[第1级],LOOKUPVALUE('商品表'[商品名称],'商品表'[序号],PATHITEM('商品表'[路径],2,INTEGER)))

【新建列】第3级 = if(PATHLENGTH('商品表'[路径])<=2,'商品表'[第2级],LOOKUPVALUE('商品表'[商品名称],'商品表'[序号],PATHITEM('商品表'[路径],3,INTEGER)))

忠告:没有作弊的公式,只能不停锻炼的大脑,思考最重要。

【5】制作层级关系

创建层次结构
将每一级添加进来
重命名

【6】放到矩阵

向下钻取:我们在《跟着孙兴华学习数据分析第五季》图表篇中讲过

我们发现红框内的显示是多余的,如果不是为了去掉它们,我们根本没必要这么麻烦,搞什么层级结构

【7】在商品表中新建列

【新建列】有几层 = PATHLENGTH('商品表'[路径]) 

// 函数我们在上面讲过了,返回路径有几层

【8】找规律

【度量值】

第1层是否被筛选 = ISFILTERED('商品表'[第1级]) 

第2层是否被筛选 = ISFILTERED('商品表'[第2级]) 

第3层是否被筛选 = ISFILTERED('商品表'[第3级]) 

筛选深度 = [第1层是否被筛选]+[第2层是否被筛选]+[第3层是否被筛选]

// True是1,False是0,加在一起,看看筛选了几个

层次深度 = max('商品表'[有几层])

总销量 = sum('销售表'[销量])

【9】解决问题

我们找到上图的两个规律,问题就解决了

【度量值】筛选等于最大层级返回空 = if([筛选深度]=[层次深度],BLANK(),[总销量])

现在我们的目的是,返回普通黄瓜、秋黄瓜、国产土豆、荷兰土豆对应的值,而不返回子级苹果、西瓜、香蕉对应的值。

以下两种新建列的方法,都可以使用,在商品表中新建列

// VAR 指定某列时,代表当前行指定单元格的值,详见《DAX神功》第1卷第14回

【度量值】第1种方法唯一值 = SELECTEDVALUE('商品表'[第一种方法])

// 《DAX神功》第2卷第19回 关于SELECTEDVALUE函数的原理

【度量值】满足两个条件 = if([筛选深度]=[层次深度] && [第1种方法唯一值],[总销量])

// 这样就返回我们需要的层级结果

我们将刚才用过的两个公式写成一个:

筛选等于最大层级返回空 = if([筛选深度]=[层次深度],BLANK(),[总销量])

满足两个条件 = if([筛选深度]=[层次深度] && [第1种方法唯一值],[总销量])

写成

结果 = if([筛选深度]=[层次深度] && [第1种方法唯一值],[总销量],if([筛选深度]=[层次深度],BLANK(),[总销量]))

终于成功了!真累!

《孙兴华讲PowerBI火力全开》PowerBI必学课程

https://www.bilibili.com/video/BV1qa4y1H7wp

《DAX神功》文字版合集:

https://www.bilibili.com/read/readlist/rl442274

《DAX神功》视频版合集:

https://www.bilibili.com/video/BV1YE411E7p3

PowerBI(DAX函数)、PowerQuery(M函数)、Python办公自动化、Python爬虫、Python数据分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等

https://www.bilibili.com/read/cv10222110 

Power BI之DAX神功:第3卷第2回 处理父子层级结构的评论 (共 条)

分享到微博请遵守国家法律