前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >​再谈 Power BI 分组的真实案例

​再谈 Power BI 分组的真实案例

作者头像
BI佐罗
发布2019-09-23 19:24:55
2.1K0
发布2019-09-23 19:24:55
举报
文章被收录于专栏:PowerBI战友联盟PowerBI战友联盟

文本为叶云老师提供,并附有示例文件。

前言

之前已经简单与大家聊过 Power BI 中的分组问题了,近日朋友又问了一个实际工作中的问题,恰巧也与分组有关,便整理之后,与众位朋友共享,再谈 Power BI 分组的博大精深。

问题

需求

现在有一张事实表,样例如下

订单ID

订单日期

邮寄方式

产品ID

销售额

US-2018-1357144

2019/4/27

二级

办公用-用品-10002717

129.696

CN-2018-1973789

2019/6/15

标准级

办公用-信封-10004832

125.44

CN-2018-1973789

2019/6/15

标准级

办公用-装订-10001505

31.92

US-2018-3017568

2019/12/9

标准级

办公用-用品-10003746

321.216

CN-2017-2975416

2018/5/31

二级

办公用-器具-10003452

1375.92

CN-2016-4497736

2017/10/27

标准级

技术-设备-10001640

11129.58

CN-2016-4497736

2017/10/27

标准级

办公用-装订-10001029

479.92

CN-2016-4497736

2017/10/27

标准级

家具-椅子-10000578

8659.84

CN-2016-4497736

2017/10/27

标准级

办公用-纸张-10001629

588

CN-2016-4497736

2017/10/27

标准级

办公用-系固-10004801

154.28

……

……

……

……

……

朋友想对各个产品ID平均销售额进行分组操作,分成以下8组

组别

最小值

最大值

小于等于100

100

100 ~ 500

100

500

500 ~ 1000

500

1000

1000 ~ 2000

1000

2000

2000 ~ 3000

2000

3000

3000 ~ 4000

3000

4000

4000 ~ 5000

4000

5000

大于等于5000

5000

朋友的解决方案

不难看出,事实表的每一行均为一张订单,所以先要得到一张中间表每个产品ID平均销售额的中间表。

于是朋友使用 Power BI 中的 DAX 构建表的方式,构建了一张中间表。公式如下:

代码语言:javascript
复制
中间表 =
SUMMARIZE ( '订单', '订单'[产品ID], "平均销售额", AVERAGE ( '订单'[销售额] ) )

结果样例如下:

然后使用 DAX 增加计算列,公式如下:

代码语言:javascript
复制
分组列 =
SWITCH (
    TRUE (),
    '中间表'[平均销售额] < 100, "小于等于100",
    '中间表'[平均销售额] >= 100
        && '中间表'[平均销售额] < 500, "100 ~ 500",
    '中间表'[平均销售额] >= 500
        && '中间表'[平均销售额] < 1000, "500 ~ 1000",
    '中间表'[平均销售额] >= 1000
        && '中间表'[平均销售额] < 2000, "1000 ~ 2000",
    '中间表'[平均销售额] >= 2000
        && '中间表'[平均销售额] < 3000, "2000 ~ 3000",
    '中间表'[平均销售额] >= 3000
        && '中间表'[平均销售额] < 4000, "3000 ~ 4000",
    '中间表'[平均销售额] >= 4000
        && '中间表'[平均销售额] < 5000, "4000 ~ 5000",
    '中间表'[平均销售额] >= 5000, "大于等于5000"
)

之后就完成了数据准备,得到了下表:

之后仅需将分组列产品ID的计数拖入表格即可得到结果。

朋友的困扰

但是老板的需求要是这么简单就好了,老板希望可以根据订单日期进行筛选,但是现在的这个方法,订单日期的筛选完全无效。

解法

看过我之前博文的战友应该能有些思路,这类问题,就应该使用 DAX 来解决,我们不做计算列,不做中间表,全都应该依靠 DAX 的模型能力。应了佐罗老师的一句名言:DAX 驱动可视化,非侵入式的模型设计。现在且听我娓娓道来。

准备

为了分组,当然要准备一张分组表,可用的方式有很多,例如再导入一张分组表等等,此处使用 DAX 表达式,构建一张分组表,公式如下:

代码语言:javascript
复制
分组表 =
DATATABLE (
    "组别", STRING,
    "最小值", INTEGER,
    "最大值", INTEGER,
    {
        { "< 100", -999999, 100 },
        { "100 ~ 500", 100, 500 },
        { "500 ~ 1000", 500, 1000 },
        { "1000 ~ 2000", 1000, 2000 },
        { "2000 ~ 3000", 2000, 3000 },
        { "3000 ~ 4000", 3000, 4000 },
        { "4000 ~ 5000", 4000, 5000 },
        { "> 5000", 5000, 999999 }
    }
)

其中 DATATABLE 函数用于构建一张表,前半部分用于说明表结构,后半部分用于填入数据。之后就得到了下表:

表达式详解

准备已成,那我们就可以构建 DAX 表达式了,分组仅用一个度量值,表达式如下:

代码语言:javascript
复制
分组方式 =
VAR CurrentItem =
    SELECTEDVALUE ( '分组表'[组别] )  // 确定所在的组别
VAR LeftValue =
    CALCULATE ( MIN ( '分组表'[最小值] ), '分组表'[组别] = CurrentItem )  //将该组的最小值作为左值
VAR RightValue =
    CALCULATE ( MIN ( '分组表'[最大值] ), '分组表'[组别] = CurrentItem )  //将该组的最大值作为右值
VAR mid_table =
    ADDCOLUMNS (
        VALUES ( '订单'[产品ID] ),
        "平均销售额", CALCULATE ( AVERAGE ( '订单'[销售额] ) )
    )  // 按照产品ID构造一张虚拟中间表
VAR ItemRange =
    FILTER ( mid_table, [平均销售额] >= LeftValue && [平均销售额] < RightValue )  // 过滤出属于最初选定组别的虚拟表的子集
RETURN
    COUNTROWS ( ItemRange )

可能有些伙伴没有看明白,我分布说明下:

  1. 由于度量值最终会和组别一起使用,那么首先要确定是针对那个组进行统计
代码语言:javascript
复制
VAR CurrentItem =
    SELECTEDVALUE ( '分组表'[组别] )
  1. 然后确定了组别,就需要确定这一组的左值和右值,一边后面用于计算
代码语言:javascript
复制
VAR LeftValue =
    CALCULATE ( MIN ( '分组表'[最小值] ), '分组表'[组别] = CurrentItem )
VAR RightValue =
    CALCULATE ( MIN ( '分组表'[最大值] ), '分组表'[组别] = CurrentItem )
  1. 之后构造一张虚拟表,是按照产品ID销售额的平均值,行为类似上文中使用 SUMMARIZE 构造的中间表
代码语言:javascript
复制
VAR mid_table =
    ADDCOLUMNS (
        VALUES ( '订单'[产品ID] ),
        "平均销售额", CALCULATE ( AVERAGE ( '订单'[销售额] ) )
    )
  1. 最后要统计出属于该分组的一个子集,统计其行数就是产品ID的计数啦。
代码语言:javascript
复制
VAR ItemRange =
    FILTER ( mid_table, [平均销售额] >= LeftValue && [平均销售额] < RightValue )
RETURN
    COUNTROWS ( ItemRange )

最后让我们一起来看看效果。

总结

最近都在写分组,但是分组却是工作中最常用的场景。战友们如果有工作中遇到的有趣的分组需求,欢迎在留言区留言,我们再交流,寻找模型驱动可视化的边界。

BI佐罗备注:PowerBI用作分析的动态性,SQL或其他分析工具对于分组都很简单,但唯有商业智能工具是天生自带动态性的。

——

延伸阅读:

PowerBI DAX 区间分组通用模式及正态分布曲线 史上最强 PowerBI 全动态 RFM 模型 2.2 版 完美得无懈可击 PowerBI 全动态 RFM 模型 2.0 版 震撼发布

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PowerBI战友联盟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 问题
      • 需求
      • 朋友的解决方案
      • 朋友的困扰
    • 解法
      • 准备
      • 表达式详解
    • 总结
    相关产品与服务
    腾讯云 BI
    腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档