目录
PowerBi的编辑查询->转换,可以实现数据表的透视列(行转列,或者叫一列变多列)和逆透视列(列转行,或者叫多列变一列)功能。
但是这种方法会修改原始数据表,在开发中,可能会遇到客户不允许我们修改表的情况,那么我们就要考虑使用DAX来实现。
1.透视列
假设我们有一张透视表:
我们想把“兴趣”列,变成两列:"偏好视频"和"偏好作者",有的,就显示对应的兴趣,没有就显示空,或者无。
做法是使用ADDCOLUMNS()增加两列。
DAX代码:
ADDCOLUMNS(
'透视表',
"偏好视频",IF(CONTAINSSTRING('透视表'[兴趣],"偏好视频"),'透视表'[兴趣],"无"),
"偏好作者",IF(CONTAINSSTRING('透视表'[兴趣],"偏好作者"),'透视表'[兴趣],"无")
)
查询视图结果:
我们再把原先的"兴趣"列进行筛除:
SELECTCOLUMNS(
ADDCOLUMNS('透视表',
"偏好视频",IF(CONTAINSSTRING('透视表'[兴趣],"偏好视频"),'透视表'[兴趣],"无"),
"偏好作者",IF(CONTAINSSTRING('透视表'[兴趣],"偏好作者"),'透视表'[兴趣],"无")
),
"客户",[客户],
"偏好视频",[偏好视频],
"偏好作者",[偏好作者]
)
得到:
原先的“兴趣”列被成功的单独分成两列统计,然后我们就可以通过将它作为计算表来进行其他统计计算,而不需要修改原始数据表
2.逆透视列
假设我们有一张逆透视表
我们要把"跑步"列和“游泳”列,合并成一个“爱好”列。
逆透视会比较麻烦一点,因为结果可能会增加行。
比如B,因为同时喜欢跑步和游泳,所以他会有两行。
解决思路是,每次我们只会用ADDCOLUMNS()处理一列,最后再把结果合并起来。
(1) 处理“游泳”列:
SELECTCOLUMNS(
ADDCOLUMNS('逆透视表',"爱好",IF('逆透视表'[游泳] = "喜欢","喜欢游泳","")),
"客户",[客户],
"爱好",[爱好]
)
因为A不喜欢游泳,所以结果有空“爱好”行,我们把它过滤掉:
FILTER(
SELECTCOLUMNS(
ADDCOLUMNS('逆透视表',"爱好",IF('逆透视表'[游泳] = "喜欢","喜欢游泳","")),
"客户",[客户],
"爱好",[爱好]
),
[爱好]<>"")
得到:
(2) 同理,处理"跑步"列:
FILTER(
SELECTCOLUMNS(
ADDCOLUMNS('逆透视表',"爱好",IF('逆透视表'[跑步] = "喜欢","喜欢跑步","")),
"客户",[客户],
"爱好",[爱好]
),
[爱好]<>"")
(3)合并:
UNION(
FILTER(
SELECTCOLUMNS(
ADDCOLUMNS('逆透视表',"爱好",IF('逆透视表'[游泳] = "喜欢","喜欢游泳","")),
"客户",[客户],
"爱好",[爱好]
),
[爱好]<>""),
FILTER(
SELECTCOLUMNS(
ADDCOLUMNS('逆透视表',"爱好",IF('逆透视表'[跑步] = "喜欢","喜欢跑步","")),
"客户",[客户],
"爱好",[爱好]
),
[爱好]<>"")
)
得到:
实际开发中,逆透视并不一定是完全转换为一列,更多情况是转换为两列。一列属性,一列值。
比如上面的表,转换后应该是"客户",“爱好”, "是否喜欢“,那么做法就更简单了,因为不需要额外处理空值:
UNION(SELECTCOLUMNS(ADDCOLUMNS('逆透视表',"爱好","跑步","是否喜欢",IF('逆透视表'[跑步]="喜欢","喜欢","不喜欢")),
"客户",[客户],
"爱好",[爱好],
"是否喜欢",[是否喜欢]),
SELECTCOLUMNS(ADDCOLUMNS('逆透视表',"爱好","游泳","是否喜欢",IF('逆透视表'[游泳]="喜欢","喜欢","不喜欢")),
"客户",[客户],
"爱好",[爱好],
"是否喜欢",[是否喜欢]))