数据分析实战-零售数据分析

零售数据分析的概念

零售行业核心指标

运营类业务指标

业绩指标

四核指标

三效指标

拓展指标

商品类业务指标

动销指标

库存指标

关联指标

会员类业务指标

存量指标

新增指标

复购指标

流失指标

项目背景

项目中为一家零售服装公司的数据集,公司有150多家门店,现需要基于数据搭建模型和运营可视化看板。

数据准备及模型搭建

数据源相关信息

数据表结构

维度表

维度表又叫查找表,通常用来做分析问题的角度。

门店信息表(Model-Dimstore)

门店信息发生变化时,比如门店状态变为撤店,门店面积增减、店员标配人数变化、新增门店相关字段,均在此表维护。门店ID是主键,不能有重复。

产品信息表(Model-Dimproduct

产品信息表记录每个产品的基础信息,产品ID是主键,深度分析门店销售业绩异常波动原因,准确、完整、丰富的产品信息是关键所在。序号字段在后期数据可视化方面用于展示品类先后顺序。

日期表(Model-Dimdates

日期表记录从年份起始日期到结束日期每一天的日期信息,其中日期字段是主键。日期表中的日期必须连续、完整。零售数据分析中,时间维度的分析是重要的分析维度之一,日期表字段的丰富程度,决定了时间维度分析的深度和广度。

会员信息表(Model-Dimmember

会员信息表记录每位会员的基础信息,其中会员ID是主键。完整的会员信息,可以精准呈现品牌消费者画像。

区域信息表(Model-Dimcity

区域信息表记录每个区域包含的省份及地级市,其中城市字段是主键。序号字段在后期数据可视化方面用于展示区域先后顺序。

产品季节表(Model-Dimproductseason

产品季节表记录每个产品季节中产品的新老品属性,其中产品季节字段是主键。通过维护产品季节表,可以快速修改产品的新老品属性,从而进行新老品分析。

事实表

销售表(Model-Factsales

销售表记录每家门店每日每位顾客(会员及非会员)每笔单据中做包含的每个产品的购买数量及金额。

销售表数据记录庞大,为了尽可能减少模型的大小,字段尽可能精简,做到"又瘦又高"。

同一个订单中可能会包含多个产品的记录数据。

进销存表(Model-Factstock

进销存表记录公司总仓及每家门店每个产品每日的进货、配货及数量。

门店分为两类,一类是具体的门店,另一类是总仓。

商品状态有3类,分别为进货、配货、销售:对于总仓而言,从厂家配送到总仓的环节定义为"进货",从总仓配送到门店的环节定义为"配货";对于门店而言,从总仓配送到门店的环节定义为"进货",门店的销售环节定义为"销售"。

任务表(Model-Facttask

任务表记录每家门店每日的任务,主要用于和门店每日实际销售额进行比较,计算销售完成率,从而也便于后续的绩效考核。任务字段的单位是元。

数据获取及转换

从Excel工作簿获取数据

tb产品季和产品季节表的区别在于,前者表示表格(超级表),后者表示Excel中的工作表。

注意导入表格字段数据类型的检查和修改,数据类型是文本的,可以不做调整。

主页-Excel工作簿-勾选tb开头的表格-转换数据-检查数据类型-关闭并应用

从文件夹获取数据

关键函数,PowerQuery中的M函数Excel.workbook()。

= Excel.workbook([Content],true)
Excel.Workbook第一个参数是要解析的二进制形式的工作簿;
Excel.Workbook第二个参数为可选参数,通过使用true,表示指定表格中的第一行作为标题;
Excel.Workbook是PowerQuery中的M函数,该函数要严格区分大小写,Excel.Workbook中字母E、W需 大写,true需小写。

主页-获取数据-选择文件夹-连接-选择文件所在路径-选择对应文件夹-转换数据-添加自定义列-输入M函数-展开自定义列-选择"Data"-删除其他列、展开"Data"列-检查字段数据类型并修改-关闭并应用

数据源路径的参数化设置

参数化设置的优势

数据源路径参数化设置后,当文件或文件夹的路径变更后,只需修改路径参数即可。

文件-管理参数-新建参数,点击管理参数可以修改参数

设置好参数后,修改M函数,点击源查看修改前的代码

修改前:= Folder.Files("D:\07项目\零售数据分析实战进阶\RetailData\销售表")

修改后:= Folder.Files(FilePath&"\销售表")

销售表前要记得加"\"

查询分组及命名

查询命名

查询报表按照其在数据模型中的作用,分为维度表和事实表。命名规则建议如下:
维度表统一使用前缀Model-Dim+名称,比如Model-Dimproduct
事实表统一使用前缀Model-Fact+名称,比如Model-Facesales

查询分组

当PowerBI中PowerQuery编辑器里面查询较多时,分组可以方便查找和管理。选中表格右键新建组,也可以把表格移动到其他组。

日期表的创建

日期表的创建方式

方法一

方法二

生成Model_Dimdates的度量值写法

复制代码
Model-Dimdates = 
VAR BeginDate = 
MIN ( 'Model-Factsales'[日期] ) // 根据实际修改
VAR EndDate =
MAX ( 'Model-Factsales'[日期] ) // 根据实际修改
RETURN
ADDCOLUMNS (
SELECTCOLUMNS (
CALENDAR (
DATE ( YEAR ( BeginDate ) - 1, 1, 1 ),
DATE ( YEAR ( EndDate ) + 1, 12, 31 )
),
"日期", [Date]
),
"年", YEAR ( [日期] ),
"季度",
SWITCH (
TRUE (),
MONTH ( [日期] ) IN { 1, 2, 3 }, 1,
MONTH ( [日期] ) IN { 4, 5, 6 }, 2,
MONTH ( [日期] ) IN { 7, 8, 9 }, 3,
MONTH ( [日期] ) IN { 10, 11, 12 }, 4
),
"年份季度",
YEAR ( [日期] ) * 10
+ SWITCH (
TRUE (),
MONTH ( [日期] ) IN { 1, 2, 3 }, 1,
MONTH ( [日期] ) IN { 4, 5, 6 }, 2,
MONTH ( [日期] ) IN { 7, 8, 9 }, 3,
MONTH ( [日期] ) IN { 10, 11, 12 }, 4
),
"月", MONTH ( [日期] ),
"月份名称", "M" & MONTH ( [日期] ),
"年月", YEAR ( [日期] ) * 100 + MONTH ( [日期] ),
"周", WEEKNUM ( [日期], 2 ),
"年份周数", YEAR ( [日期] ) * 100 + WEEKNUM ( [日期], 2 ),
"星期", WEEKDAY ( [日期], 2 ),
"日",DAY([日期]))

标记为日期表

表格视图-选中Model-Dimdates-表工具-标记为日期表-选择日期列将其标记为日期列-保存

数据模型的搭建

整体搭建

按主题搭建

基于Model_Factsales

基于Model_Factstock

基于Model_Facttask

运营分析

经营概况

页面构建思路

核心指标分析

销售额

复制代码
Core 销售额 = SUM('Model-Factsales'[金额])
销售额 PY = CALCULATE([Core 销售额],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]))
销售额 PY View = 
CALCULATE(
    [Core 销售额],
    SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),
    'Model-Dimdates'[可比日期] = TRUE()
)

销售额 PY:表示同期销售额

销售额PY View:表示同期可比日期的销售额

销售表的日期到2019/8/20,所以Core 销售额只到2019/8/20,销售额 PY返回同期的销售额,也就是2018/8/1-2018/8/31的销售额,销售额PY View返回同期可比日期的销售额,2019/8/20之后的日期属于未来日期,不能比较,销售额PY View数据只到2019/8/20。

复制代码
最后报表日期 = MAXX(ALL('Model-Factsales'[日期]),'Model-Factsales'[日期])

MAXX:返回日期表中最大的日期,最后报表日期为2019/8/20

复制代码
计算列

可比日期 = 
VAR LastSalesDateinDimdates = 
    TREATAS({[最后报表日期]},'Model-Dimdates'[日期])
VAR LastSalesDateLastYear = 
    SAMEPERIODLASTYEAR(LastSalesDateinDimdates)
RETURN
    'Model-Dimdates'[日期] <= LastSalesDateLastYear
        || AND(
            'Model-Dimdates'[日期] <= [最后报表日期],
            'Model-Dimdates'[年] = YEAR([最后报表日期])
        )

TREATAS({[最后报表日期]}, 'Model-Dimdates'[日期]):将最后报表日期转换为日期表的日期格式,建立关系

SAMEPERIODLASTYEAR(LastSalesDateinDimdates):获取去年同期的日期

返回逻辑第一部分:'Model-Dimdates'[日期] <= LastSalesDateLastYear

选择所有小于等于去年最后报表日期的日期

第二部分:AND('Model-Dimdates'[日期] <= [最后报表日期], 'Model-Dimdates'[年] = YEAR([最后报表日期]))

选择当前年度且小于等于最后报表日期的日期

假设最后报表日期为2024/6/15

选择插入KPI图,设置格式,即可实现可视化,通过KPI图可以查看当期销售额和同比增速。

销售完成率

复制代码
Core 销售目标 = SUM('Model-Facttask'[任务])
Core 销售目标 View = CALCULATE([Core 销售目标],FILTER('Model-Dimdates','Model-Dimdates'[日期]<=[最后报表日期]))
Core 销售完成率 = DIVIDE([Core 销售额],[Core 销售目标 View])

如果是用销售额除以销售目标,销售完成率为56.63%,除以销售目标View,销售完成率为87.12%。销售目标View只计算到最后报表日期的销售目标。

折扣率

复制代码
Core 吊牌金额 = SUMX('Model-Factsales',[吊牌价]*[数量])
Core 折扣率 = DIVIDE([Core 销售额],[Core 吊牌金额])
折扣率 PY View = 
CALCULATE(
    [Core 折扣率],
    SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),
    'Model-Dimdates'[可比日期] = TRUE()
)

公司售罄率

复制代码
售罄率 公司 新品 = 
DIVIDE(
    CALCULATE(
        [累计销量 新品],
        REMOVEFILTERS('Model-Dimcity'),
        REMOVEFILTERS('Model-Dimstore')
    ),
    [累计入库 总仓 新品]
)
售罄率 公司 同期新品 PY VIEW = CALCULATE ( [售罄率 公司 同期新品 PY], 'Model-Dimdates'[可比日期] = TRUE() )

本期销量 = [Core 销量]

本期入库 总仓 = 
CALCULATE(
    SUM('Model-Factstock'[数量]),
    'Model-Factstock'[状态] = "进货",
    REMOVEFILTERS('Model-Dimcity'),
    REMOVEFILTERS('Model-Dimstore'),
    'Model-Factstock'[门店ID] = "AAA"
)

累计销量 新品 = 
IF(
    MIN('Model-Dimdates'[日期]) <= [最后报表日期],
    CALCULATE(
        [本期销量],
        FILTER(
            ALL('Model-Dimdates'),
            'Model-Dimdates'[日期] <= MAX('Model-Dimdates'[日期])
        ),
        'Model-Dimproductseason'[新老品] = "新品"
    )
)

累计入库 总仓 新品 = 
IF(
    MIN('Model-Dimdates'[日期]) <= [最后报表日期],
    CALCULATE(
        [本期入库 总仓],
        FILTER(
            ALL('Model-Dimdates'),
            'Model-Dimdates'[日期] <= MAX('Model-Dimdates'[日期])
        ),
        'Model-Dimproductseason'[新老品] = "新品"
    )
)

'Model-Dimdates'[日期] <= MAX('Model-Dimdates'[日期]):筛选出所有小于等于当前日期的日期,再筛选出新品,统计这段日期的入库新品数量和销售新品数量。

复制代码
累计销量 同期新品 = 
IF (
    MIN ( 'Model-Dimdates'[日期] ) <= [最后报表日期],
    CALCULATE (
        [本期销量],
        FILTER (
            ALL ( 'Model-Dimdates' ),
            'Model-Dimdates'[日期] <= MAX ( 'Model-Dimdates'[日期] )
        ),
        'Model-Dimproductseason'[新老品] = "同期新品"
    )
)

累计入库 总仓 同期新品 = 
IF(
    MIN('Model-Dimdates'[日期]) <= [最后报表日期],
    CALCULATE(
        [本期入库 总仓],
        FILTER(
            ALL('Model-Dimdates'),
            'Model-Dimdates'[日期] <= MAX('Model-Dimdates'[日期])
        ),
        'Model-Dimproductseason'[新老品] = "同期新品"
    )
)

累计销量 同期新品 PY = CALCULATE ( [累计销量 同期新品], SAMEPERIODLASTYEAR ( 'Model-Dimdates'[日期] ) )

累计入库 总仓 同期新品 PY = CALCULATE ( [累计入库 总仓 同期新品], SAMEPERIODLASTYEAR ( 'Model-Dimdates'[日期] ) )

售罄率 公司 同期新品 PY = 
DIVIDE(
    CALCULATE(
        [累计销量 同期新品 PY],
        REMOVEFILTERS('Model-Dimcity'),
        REMOVEFILTERS('Model-Dimstore')
    ),
    [累计入库 总仓 同期新品 PY]
)

店效 可比店

复制代码
店效 可比店 = 
CALCULATE(
    DIVIDE([Core 销售额],COUNTROWS('Model-Dimstore')),
    'Model-Dimstore'[可比类型] = "可比店",
    'Model-Dimstore'[门店状态] = "营业中"
)

店效 可比店 PY View = 
CALCULATE(
    [店效 可比店],
    SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),
    'Model-Dimdates'[可比日期] = TRUE()
)

计算列

可比类型 = VAR CurYear = YEAR([最后报表日期])
RETURN
    SWITCH(TRUE(),
        [开业日期] <= DATE(CurYear-1,1,1),"可比店",
        [开业日期] <= DATE(CurYear,1,1),"满年店",
        "非满年店"
    )

坪效 可比店

复制代码
坪效 可比店 = 
CALCULATE(
    DIVIDE([Core 销售额],SUM('Model-Dimstore'[门店面积])),
    'Model-Dimstore'[可比类型] = "可比店",
    'Model-Dimstore'[门店状态] = "营业中"
)

坪效 可比店 PY View = 
CALCULATE(
    [坪效 可比店],
    SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),
    'Model-Dimdates'[可比日期] = TRUE()
)

人效 可比店

复制代码
人效 可比店 = 
CALCULATE(
    DIVIDE([Core 销售额],SUM('Model-Dimstore'[店员标配人数])),
    'Model-Dimstore'[可比类型] = "可比店",
    'Model-Dimstore'[门店状态] = "营业中"
)

人效 可比店 PY View = 
CALCULATE(
    [人效 可比店],
    SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),
    'Model-Dimdates'[可比日期] = TRUE()
)

单据数计算逻辑

客单价

复制代码
销售额 正单有效法 = CALCULATE([Core 销售额],FILTER(VALUES('Model-Factsales'[订单ID]),[Core 销量]>0))

单据数 正单有效法 = 
CALCULATE(
    DISTINCTCOUNT('Model-Factsales'[订单ID]),
    FILTER(
        VALUES('Model-Factsales'[订单ID]),[Core 销量]>0
    )
)

客单价 正单有效法 = DIVIDE([销售额 正单有效法],[单据数 正单有效法])

客单价 PY View = CALCULATE([客单价 正单有效法],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),'Model-Dimdates'[可比日期]=TRUE())

件单价

复制代码
销量 正单有效法 = CALCULATE([Core 销量],FILTER(VALUES('Model-Factsales'[订单ID]),[Core 销量]>0))

件单价 正单有效法 = DIVIDE([销售额 正单有效法],[销量 正单有效法])

件单价 PY View = CALCULATE([件单价 正单有效法],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),'Model-Dimdates'[可比日期]=TRUE())

单据数

复制代码
单据数 正单有效法 = 
CALCULATE(
    DISTINCTCOUNT('Model-Factsales'[订单ID]),
    FILTER(
        VALUES('Model-Factsales'[订单ID]),[Core 销量]>0
    )
)

单据数 PY View = CALCULATE([单据数 正单有效法],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),'Model-Dimdates'[可比日期]=TRUE())

连带率

复制代码
连带率 正单有效法 = DIVIDE([销量 正单有效法],[单据数 正单有效法])

门店数

指历史开设的门店数,包括营业门店数及关店数。这里只考虑处于营业状态的门店数量。

复制代码
门店数 = 
VAR MaxDate = 
    MAX('Model-Dimdates'[日期])
RETURN
    CALCULATE(
        DISTINCTCOUNT('Model-Dimstore'[门店ID]),
        'Model-Dimstore'[开业日期] <= MaxDate,
        OR('Model-Dimstore'[撤店日期] > MaxDate,'Model-Dimstore'[撤店日期] = BLANK())
    )

门店数 PY = 
CALCULATE (
    [门店数],
    SAMEPERIODLASTYEAR ( 'Model-Dimdates'[日期] ),
    'Model-Dimdates'[可比日期] = TRUE ()
)

新会员数量

返回非重复的会员ID列,再去除空值,会员ID对应的最小日期如果在日期表中就返回TRUE,统计返回TRUE的会员ID数量。

复制代码
会员 新会员 = 
VAR UserCur = 
    FILTER(
        VALUES('Model-Factsales'[会员ID]),
        'Model-Factsales'[会员ID]<>BLANK()
    )
VAR UserNew = 
    FILTER(
        UserCur,
        VAR FirstPoint = 
            CALCULATE(MIN('Model-Factsales'[日期]),ALL('Model-Dimdates'))
        RETURN
            FirstPoint IN VALUES('Model-Dimdates'[日期])
    )
RETURN
    CALCULATE(DISTINCTCOUNT('Model-Factsales'[会员ID]),UserNew)

会员 新会员 PY View = CALCULATE([会员 新会员],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),'Model-Dimdates'[可比日期]=TRUE())

会员数量

复制代码
会员 有消数量 = CALCULATE(DISTINCTCOUNT('Model-Factsales'[会员ID]),'Model-Factsales'[会员ID]<>BLANK())

会员 有消数量 PY View = CALCULATE([会员 有消数量],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),'Model-Dimdates'[可比日期]=TRUE())

会员消费占比

复制代码
会员 销售额占比 = 
VAR MemberSales = 
    CALCULATE([Core 销售额],'Model-Factsales'[会员ID]<>BLANK())
RETURN
    DIVIDE(MemberSales,[Core 销售额])

会员 销售额占比 PY View = CALCULATE([会员 销售额占比],SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),'Model-Dimdates'[可比日期]=TRUE())

复购率

复制代码
会员 复购人数 = 
COUNTROWS(
    FILTER(
        VALUES('Model-Factsales'[会员ID]),
        'Model-Factsales'[会员ID]<>BLANK()
        &&[单据数 正单有效法]>=2
    )
)

会员 年平均动态复购人数 = 
IF( 
    MIN('Model-Dimdates'[日期])<=[最后报表日期],
    CALCULATE(
        [会员 复购人数],
        DATESINPERIOD('Model-Dimdates'[日期],MIN('Model-Dimdates'[日期])-1,-1,YEAR)
    )
)

会员 年平均动态复购率 = 
VAR X = 
    CALCULATE(
        [会员 有消数量],
        DATESINPERIOD('Model-Dimdates'[日期],MIN('Model-Dimdates'[日期])-1,-1,YEAR)
    )
RETURN
    IF(MIN('Model-Dimdates'[日期])<=[最后报表日期],DIVIDE([会员 年平均动态复购人数],X))

会员 年平均动态复购率 PY View = 
CALCULATE(
    [会员 年平均动态复购率],
    SAMEPERIODLASTYEAR('Model-Dimdates'[日期]),
    'Model-Dimdates'[可比日期] = TRUE()
)

各区域销售额及店效对比

可以点击图片上方的向下箭头,向下钻取查看每一个省份对应城市的详细数据。

销售额月度达成情况及同期对比

在X轴处右键选择向上钻取可以只显示月份数据,点击图片上方的向下箭头可以实现向下钻取,如点击M1可以查看一月份每天的销售额。异常月份向下钻取到日期进一步分析。

各部门销售额达成情况及同期对比

在表格视图中选择Model_Dimcity表格,选中区域列-列工具-排序-按列排序-序列,这样就可以实现X轴按照营销一区、营销二区...排列。同样可以在异常区域向下钻取至单店,找到销售异常的个体。

各经营业态及经营模式销售对比

用按钮制作标题,将两个条形图和按钮选择格式-组合,形成一个整体。

区域分析

页面构建思路

核心指标区域结构分析

各时间区间基础度量值

昨日、本周至今、本月至今、本年至今是与绩效考核、日常经营管理高度相关的时间区间,最近7日、最近30日、最近1年则是用于辅助决策的时间区间。以销售额为例,可比店店效、销售完成率、折扣率、单据数、客单价、件单价、连带率类似。

复制代码
昨日 销售额 = 
VAR X = [最后报表日期]
RETURN
CALCULATE (
    [Core 销售额], 'Model-Dimdates'[日期] = X )
//     FILTER ( ALL ( 'Model-Dimdates' ), 'Model-Dimdates'[日期] = [最后报表日期] )
// )

最近7日 销售额 = 
CALCULATE(
    [Core 销售额],
    DATESINPERIOD('Model-Dimdates'[日期],[最后报表日期],-7,DAY)
)

最近30日 销售额 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([Core 销售额],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近1年 销售额 = 
CALCULATE(
    [Core 销售额],
    DATESINPERIOD('Model-Dimdates'[日期],[最后报表日期],-1,YEAR)
)

本周至今 销售额 = 
CALCULATE(
    [Core 销售额],
    FILTER(
        ALL('Model-Dimdates'),
        'Model-Dimdates'[年份周数] = YEAR([最后报表日期])*100+WEEKNUM([最后报表日期],2)
    )
)

本月至今 销售额 = 
CALCULATE(
    [Core 销售额],
    FILTER(
        ALL('Model-Dimdates'),
        'Model-Dimdates'[年月] = YEAR([最后报表日期])*100+MONTH([最后报表日期])
    )
)

本年至今 销售额 = 
CALCULATE(
    [Core 销售额],
    FILTER(ALL('Model-Dimdates'),'Model-Dimdates'[年]=YEAR([最后报表日期]))
)

DATESINPERIOD('Model-Dimdates'[日期],[最后报表日期],-7,DAY):以天为单位,最后报表日期为起始日期,往前倒推7天。

以销售额为例,上述时间区间的同期度量值写法如下:

复制代码
昨日 销售额 PY = 
CALCULATE(
    [Core 销售额],
    FILTER(ALL('Model-Dimdates'[日期]),'Model-Dimdates'[日期]=[MaxDateLastYear]))

最近7日 销售额 PY = 
VAR MaxDate = [最后报表日期]
VAR MaxDatewithDimdates = TREATAS({MaxDate},'Model-Dimdates'[日期])
VAR MaxDateLastYear = SAMEPERIODLASTYEAR(MaxDatewithDimdates)
RETURN
    CALCULATE(
        [Core 销售额],
        DATESINPERIOD('Model-Dimdates'[日期],MaxDateLastYear,-7,DAY)
    )

最近30日 销售额 PY = 
VAR MaxDate = [最后报表日期]
VAR MaxDatewithDimdates = TREATAS({MaxDate},'Model-Dimdates'[日期])
VAR MaxDateLastYear = SAMEPERIODLASTYEAR(MaxDatewithDimdates)
RETURN
    CALCULATE(
        [Core 销售额],
        DATESINPERIOD('Model-Dimdates'[日期],MaxDateLastYear,-30,DAY)
    )

最近1年 销售额 PY = 
VAR MaxDate = [最后报表日期]
VAR MaxDatewithDimdates = TREATAS({MaxDate},'Model-Dimdates'[日期])
VAR MaxDateLastYear = SAMEPERIODLASTYEAR(MaxDatewithDimdates)
RETURN
    CALCULATE(
        [Core 销售额],
        DATESINPERIOD('Model-Dimdates'[日期],[MaxDateLastYear],-1,YEAR)
    )

本周至今 销售额 PY = 
VAR X = YEAR([最后报表日期])
VAR Y = WEEKNUM([最后报表日期],2)
VAR Z = WEEKDAY([最后报表日期],2)
RETURN
    CALCULATE(
        [Core 销售额],
        FILTER(
            ALL('Model-Dimdates'),
            'Model-Dimdates'[年] = X-1 && 'Model-Dimdates'[周] = Y && 'Model-Dimdates'[星期] <=Z)
    )

本月至今 销售额 PY = 
CALCULATE(
    [Core 销售额],
    FILTER(
        ALL('Model-Dimdates'),
        'Model-Dimdates'[年月] = (YEAR([最后报表日期])-1)*100+MONTH([最后报表日期])
    ),
    'Model-Dimdates'[可比日期]=TRUE()
)

本年至今 销售额 PY = 
 CALCULATE(
    [Core 销售额],
    FILTER(ALL('Model-Dimdates'),'Model-Dimdates'[年] = YEAR([最后报表日期])-1),
    'Model-Dimdates'[可比日期] = TRUE()
 )

'Model-Dimdates'[年] = X-1 && 'Model-Dimdates'[周] = Y && 'Model-Dimdates'[星期] <=Z):X表示最后报表日期的年份,Y表示最后报表日期是每年的第几周,Z最后报表日期是一周的周几;返回结果是去年相同周次的日期,如果Y是16,Z是周四,那么返回的日期就是去年第16周的周一、周二、周三、周四。

最近1年销售额:最后报表日期向前推进365天,比如最后报表日期为2019/8/20,返回的日期是2018/8/21-2019/8/20,不是2018/1/1-2018/12/31

本年至今销售额:最后报表日期为2019/8/20,返回的日期是2019/1/1-2019/8/20

单指标动态时间区间度量值

写好销售额本期和同期各时间区间度量值,将本期和同期各时间区间的销售额分别进行整合,构造本期和同期的动态销售额,使其可以随着外部筛选条件的改变而显示不同时间区间的销售额。要实现这一效果,需构造一个包含各时间区间的辅助表。

切换表格视图-新建表,这里没有限制数据类型,选择列工具-按列排序-序号,将序号列用于排序。

复制代码
辅助:日期期间表 = 
SELECTCOLUMNS(
    {
        ("昨日",1),
        ("本周至今",2),
        ("本月至今",3),
        ("本年至今",4),
        ("最近7日",5),
        ("最近30日",6),
        ("最近1年",7)
    },
    "时间区间",[Value1],
    "序号",[Value2]
)

以销售额为例,本期、同期动态销售额的写法如下:

复制代码
动态 销售额 = 
SWITCH (
    TRUE (),
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "昨日", [昨日 销售额],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "本周至今", [本周至今 销售额],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "本月至今", [本月至今 销售额],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "本年至今", [本年至今 销售额],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "最近7日", [最近7日 销售额],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "最近30日", [最近30日 销售额],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "最近1年", [最近1年 销售额],
    [昨日 销售额]
)

动态 销售额 PY = 
SWITCH (
    TRUE (),
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "昨日", [昨日 销售额 PY],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "本周至今", [本周至今 销售额 PY],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "本月至今", [本月至今 销售额 PY],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "本年至今", [本年至今 销售额 PY],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "最近7日", [最近7日 销售额 PY],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "最近30日", [最近30日 销售额 PY],
    SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "最近1年", [最近1年 销售额 PY],
    [昨日 销售额 PY]
)

SELECTEDVALUE ( '辅助:日期期间表'[时间区间] ) = "昨日", [昨日 销售额 PY]:辅助:日期期间表中列时间区间的值等于"昨日",返回[昨日 销售额 PY]。

多指标动态时间区间度量值

接下来将各项指标的动态度量值进一步整合,同样需要构造一个包含多项指标的KPI辅助表。同样按照"排序"列排序。

KPI列的数据类型是字符,排序的数据类型是整数。

复制代码
辅助:核心KPI = 
DATATABLE(
    "KPI",STRING,
    "排序",INTEGER,
    {
    {"销售额",1},
    {"可比店店效",2},
    {"销售完成率",3},
    {"折扣率",4},
    {"单据数",5},
    {"客单价",6},
    {"件单价",7},
    {"连带率",8}
    }
)

接下来构造度量值动态KPI、动态KPI PY、动态KPI YOY%,写法如下:

复制代码
动态 KPI = 
SWITCH (
    TRUE (),
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "销售额", [动态 销售额],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "可比店店效", [动态 店效],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "销售完成率", [动态 完成率],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "折扣率", [动态 折扣率],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "单据数", [动态 单据数],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "客单价", [动态 客单价],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "件单价", [动态 件单价],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "连带率", [动态 连带率]
)

动态 KPI PY = 
SWITCH (
    TRUE (),
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "销售额", [动态 销售额 PY],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "可比店店效", [动态 店效 PY],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "折扣率", [动态 折扣率 PY],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "单据数", [动态 单据数 PY],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "客单价", [动态 客单价 PY],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "件单价", [动态 件单价 PY],
    SELECTEDVALUE ( '辅助:核心KPI'[KPI] ) = "连带率", [动态 连带率 PY]
)

动态 KPI YOY% = DIVIDE ( [动态 KPI] - [动态 KPI PY], [动态 KPI PY] )

动态时间区间切片器制作

插入切片器,将辅助:日期期间表中的时间区间列拉入字段,切片器样式选择磁贴。要先对时间区间进行排序才能有图示的顺序。

插入切片器,将辅助:核心KPI的KPI列拉入字段,切片器样式选择垂直列表,切片器标头勾选挂起图标。

折线图和簇状柱形图制作

插入折线和簇状柱形图,标题使用动态标题。将区域、动态KPI、动态KPI PY、动态 KPI YOY%分别拖入X轴、列Y轴、行Y轴。

复制代码
标题 KPI对比 = SELECTEDVALUE('辅助:日期期间表'[时间区间]) & SELECTEDVALUE('辅助:核心KPI'[KPI]) & "同期对比"

重点城市帕累托图制作

先计算重点城市的销售额累计占比,度量值写法如下:

复制代码
销售额累计占比 按城市 动态日期 = 
VAR CurSales = [动态 销售额]
VAR CumulatedSales = 
    CALCULATE(
        [动态 销售额],
        FILTER(ALLSELECTED('Model-Dimcity'[城市]),[动态 销售额] >= CurSales)
    )
VAR AllSales = CALCULATE([动态 销售额],ALLSELECTED('Model-Dimcity'))
RETURN
    DIVIDE(CumulatedSales,AllSales)

ALLSELECTED('Model-Dimcity'[城市]):保留当前外部的切片器/筛选器选择的所有城市,但移除当前行上下文对城市的筛选。

ALL和ALLSELECTED的区别:ALL移除所有筛选器,ALLSELECTED仅移除当前上下文的筛选,保留切片器、页面筛选器、报表筛选器的影响。

FILTER(ALLSELECTED('Model-Dimcity'[城市]),[动态 销售额] >= CurSales):筛选出大于等于当前上下文城市动态销售额的城市。

复制代码
销售额累计占比 按城市 配色 = 
VAR CumulatesRatio = [销售额累计占比 按城市 动态日期]
RETURN
    SWITCH (
        TRUE (),
        CumulatesRatio <= 0.7, "#7ACA00",
        CumulatesRatio <= 0.9, "#337489",
        "#ff0000"
    )

标题 重点城市帕累托 = "重点城市" & SELECTEDVALUE( '辅助:日期期间表'[时间区间] ) & "销售额帕累托分析"

插入帕累托图,将城市、动态销售额、销售额累计占比 按城市 动态日期分别拖动X轴、列Y轴、行Y轴,在设置视觉对象格式-常规-标题-fx-格式样式选择字段值、基于标题 重点城市帕累托字段。

门店销售排名

页面构建思路

核心度量值说明

复制代码
排名 门店 销售额 DESC = 
IF(
    HASONEVALUE('Model-Dimstore'[门店名称]),
    RANKX(ALLSELECTED('Model-Dimstore'),[动态 销售额])
)

HASONEVALUE('Model-Dimstore'[门店名称]):检查当前筛选上下文中,指定列是否只有一个唯一值,如果只有唯一值则返回TRUE。

RANKX:按照动态 销售额为门店排序,默认降序。

如果这里用的是ALL则是对所有门店进行排名,用ALLSELECTED则是对筛选器筛选出的门店进行排名。

IF逻辑:如果只显示一个门店计算并显示该门店排名,如果显示多个门店或总计行返回BLANK()(空值)

由于Model-Dimstore是维度表,每个门店名称都应该是唯一的,如果出现两个相同的门店名称说明数据有问题,不会返回该门店的排名。

门店销售额排名

筛选营销二区湖北省的门店,插入表,将相应的字段拖入列。

不同维度的动态销售额分析

单店分析

页面构建思路

核心指标关键时间区间对比分析

日均单据数度量值

复制代码
本月至今 单据数 日均 = 
CALCULATE(
    DIVIDE([单据数 正单有效法],COUNTROWS('Model-Dimdates')),
    FILTER(
        ALL('Model-Dimdates'),
        'Model-Dimdates'[年月] = YEAR([最后报表日期])*100+MONTH([最后报表日期])
    )
)

本年至今 单据数 日均 = 
CALCULATE(
    DIVIDE([单据数 正单有效法],COUNTROWS('Model-Dimdates')),
    FILTER(ALL('Model-Dimdates'),'Model-Dimdates'[年] = YEAR([最后报表日期]))
)

多行卡制作

"按钮"+多行卡,拖入对应的度量值。

核心指标当月趋势分析

核心指标当月度量值

核心指标当月趋势图始终显示报表刷新日所在月份的销售业绩,时间区间不随外部时间筛选变化而变化。相关当月度量值写法如下:

复制代码
销售额 当月 = 
IF(
    MAX('Model-Dimdates'[年月]) = MONTH([最后报表日期]) + YEAR([最后报表日期])*100,
    [Core 销售额]
)

销售完成率 当月 = 
IF(
    MAX('Model-Dimdates'[年月]) = MONTH([最后报表日期]) + YEAR([最后报表日期])*100,
    [Core 销售完成率]
)

客单价 当月 = 
IF(
    MAX('Model-Dimdates'[年月]) = MONTH([最后报表日期])+YEAR([最后报表日期])*100,
    [客单价 正单有效法]
)

连带率 当月 = 
IF(
    MAX('Model-Dimdates'[年月]) = MONTH([最后报表日期]) + YEAR([最后报表日期])*100,
    [连带率 正单有效法]
)

销售额完成率移动均值度量值

相关度量值写法如下:

复制代码
销售额 7日平均 = 
VAR Last7Days = 
    DATESINPERIOD('Model-Dimdates'[日期],MAX('Model-Dimdates'[日期]),-7,DAY)
RETURN
    DIVIDE(CALCULATE([Core 销售额],Last7Days),7)

完成率 7日平均 = 
VAR Last7Days = 
    DATESINPERIOD('Model-Dimdates'[日期],MAX('Model-Dimdates'[日期]),-7,DAY)
VAR AvgTask = 
    DIVIDE(CALCULATE([Core 销售目标 View],Last7Days),7)
RETURN 
    DIVIDE([销售额 7日平均],AvgTask)

完成率 当月 7日平均 = 
IF(
    MAX('Model-Dimdates'[日期])>EOMONTH([最后报表日期],-1) 
        && MAX('Model-Dimdates'[日期])<=[最后报表日期],
    [完成率 7日平均]
)

EOMONTH([最后报表日期],-1):返回最后报表日期所在月份的上一个月份的最后一天。

为什么销售额 7日平均和完成率 7日平均是用MAX('Model-Dimdates'[日期]),而不是用最后报表日期?

如果查看的是2019/1/1-2019/1/10这段日期的销售额 7日平均,最后报表日期假设是1.15,用MAX('Model-Dimdates'[日期])返回的结果是1.4-1.10的平均值,用最后报表日期返回的是1.9-1.15,那么只能查看1.10的数据。

核心指标当月趋势图制作

插入折线和簇状柱形图,将对应的度量值拖动到相应的字段。

近30日销售完成率移动均值趋势

复制代码
完成率 7日平均 近30日 = 
IF(
    MAX('Model-Dimdates'[日期])<=[最后报表日期]
        && MAX('Model-Dimdates'[日期])>[最后报表日期] - 30,
    [完成率 7日平均]
)

新品款色数及销售额同期对比

新老品业务概念

新品及同期新品款色数度量值

复制代码
款色数 新品 = 
VAR Maxdate = MAX('Model-Dimdates'[日期])
RETURN
    CALCULATE(
        DISTINCTCOUNT('Model-Factstock'[商品ID]),
        'Model-Dimproductseason'[新老品] = "新品",
        'Model-Dimdates'[日期]<=Maxdate
    )

款色数 同期新品 PY = 
VAR Maxdate = LASTDATE('Model-Dimdates'[日期])
VAR MaxdateLastyear = SAMEPERIODLASTYEAR(Maxdate)
RETURN
    CALCULATE(
        DISTINCTCOUNT('Model-Factstock'[商品ID]),
        'Model-Dimproductseason'[新老品] = "同期新品",
        'Model-Dimdates'[日期] <= MaxdateLastyear
    )

新品及同期新品款色旋风图

不同品类的款色数本期同期对比,销售额本期同期对比。

开关店分析

页面构建思路

开店趋势及结构分析

开关店场景度量值

相关度量值写法如下:

复制代码
门店数 新增 = 
CALCULATE(
    DISTINCTCOUNT('Model-Dimstore'[门店ID]),
    'Model-Dimstore'[开业日期] IN VALUES('Model-Dimdates'[日期])
)

门店数 撤店 = 
CALCULATE(
    DISTINCTCOUNT('Model-Dimstore'[门店ID]),
    'Model-Dimstore'[撤店日期] IN VALUES('Model-Dimdates'[日期])
)

门店数 净增 = [门店数 新增]-[门店数 撤店]

开关店场景"瀑布图"

插入瀑布图,将对应度量值拖动对应区域。从月份和区域两个角度分析。

开关店详情对比

门店数相关度量值

相关度量值写法如下:

复制代码
门店数 = 
VAR MaxDate = 
    MAX('Model-Dimdates'[日期])
RETURN
    CALCULATE(
        DISTINCTCOUNT('Model-Dimstore'[门店ID]),
        'Model-Dimstore'[开业日期] <= MaxDate,
        OR('Model-Dimstore'[撤店日期] > MaxDate,'Model-Dimstore'[撤店日期] = BLANK())
    )

门店数 年初始 = CALCULATE([门店数],PREVIOUSDAY(STARTOFYEAR('Model-Dimdates'[日期])))

门店数 期末 = [门店数 年初始]+CALCULATE([门店数 净增],DATESYTD('Model-Dimdates'[日期]))

STARTOFYEAR('Model-Dimdates'[日期]):返回筛选日期所在年份的第一天

PREVIOUSDAY(STARTOFYEAR('Model-Dimdates'[日期])):返回上一年度的最后一天

比如筛选日期是2019/2/13,STARTOFYEAR('Model-Dimdates'[日期])返回的是2019/1/1,PREVIOUSDAY返回的是2018/12/31。

DATESYTD('Model-Dimdates'[日期]):返回年初到至今的日期。比如筛选日期是2019/2/13,返回的日期是2019/1/1-2019/2/13。

开关店详情矩阵

插入矩阵,将区域和省份拖入行,将门店数 年初始、门店数 新增、门店数 撤店、门店数 净增、门店数 期末拖入列。样式选择稀疏、布局选择紧凑,值设置文本(奇数行)和备用文本(偶数行)的文本颜色和背景色就可以实现图示效果。

销售预测

页面构建思路

最近30日业绩指标拆解

相关度量值写法如下:

复制代码
最近30日 销售额 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([Core 销售额],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 单据数 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([单据数 正单有效法],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 客单价 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([客单价 正单有效法],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 件单价 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([件单价 正单有效法],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 连带率 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([连带率 正单有效法],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 吊牌单价 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([Core 平均吊牌价],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 折扣率 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([Core 折扣率],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

最近30日 完成率 = 
VAR N = [最后报表日期]
RETURN
    CALCULATE([Core 销售完成率],DATESINPERIOD('Model-Dimdates'[日期],N,-30,DAY))

历史同比法销售预测

模型业务逻辑

动态参数设定

建模-参数-新建参数-数值范围

设定参数名称、数据类型、最小值、最大值、增量

格式操作:属性-高级选项-响应关闭、值-值-字体-字体颜色、

模型构建

相关度量值写法如下:

复制代码
销售额 YOY% 最近30日 = 
VAR X = [最后报表日期]
VAR Last30Days = DATESINPERIOD('Model-Dimdates'[日期],X,-30,DAY)
VAR YTDCY = CALCULATE([Core 销售额],Last30Days)
VAR YTDPY = CALCULATE([Core 销售额],SAMEPERIODLASTYEAR(Last30Days))
RETURN
    DIVIDE(YTDCY-YTDPY,YTDPY)

预测 销售额 历史同比法 未来N天 = 
VAR X = [最后报表日期]
VAR YOY = [销售额 YOY% 最近30日]
RETURN
    CALCULATE(
        [Core 销售额],
        SAMEPERIODLASTYEAR(
            DATESINPERIOD('Model-Dimdates'[日期],X+1,'参数-预测天数'[参数-预测天数 值],DAY)
        )
    )*(1+YOY)

预测 完成率 历史同比法 未来N天 = 
VAR X = [最后报表日期]
VAR Task = 
    CALCULATE(
        SUM('Model-Facttask'[任务]),
        DATESINPERIOD('Model-Dimdates'[日期],X+1,'参数-预测天数'[参数-预测天数 值],DAY)
    )
RETURN
    DIVIDE([预测 销售额 历史同比法 未来N天],Task)

二级指标目标设定及策略调整

模型业务逻辑

基于杜邦分析法的逻辑拆解

理想的杜邦分析法逻辑拆解

动态预测模型构建

复制代码
预测 单据数 杜邦分析法 未来N日 = 
VAR X = [最后报表日期]
RETURN
    CALCULATE([单据数 正单有效法],
        SAMEPERIODLASTYEAR(
            DATESINPERIOD('Model-Dimdates'[日期],X+1,'参数-预测天数'[参数-预测天数 值],DAY)
        )
    )*(1+[参数-单据同比增长率 值])

预测 吊牌价 杜邦分析法 未来N日 = 
VAR X = [最后报表日期]
RETURN
    CALCULATE([Core 平均吊牌价],
        SAMEPERIODLASTYEAR(
            DATESINPERIOD(
                'Model-Dimdates'[日期],X+1,'参数-预测天数'[参数-预测天数 值],DAY)
        )
    )

预测 客单价 杜邦分析法 未来N日 = 
[预测 吊牌价 杜邦分析法 未来N日]*
[参数-折扣率预测 值]*
[参数-连带率预测 值]

预测 销售额 杜邦分析法 未来N天 = 
[预测 单据数 杜邦分析法 未来N日]*
[预测 吊牌价 杜邦分析法 未来N日]*
[参数-折扣率预测 值]*
[参数-连带率预测 值]

预测 完成率 杜邦分析法 未来N天 = 
VAR X = [最后报表日期]
VAR Task = 
    CALCULATE(
        SUM('Model-Facttask'[任务]),
        DATESINPERIOD('Model-Dimdates'[日期],X+1,'参数-预测天数'[参数-预测天数 值],DAY)
    )
RETURN
    DIVIDE([预测 销售额 杜邦分析法 未来N天],Task)

单据数的同比增长率、折扣率、连带率是指同期的数据,与预测的时间窗口必须一致。单据数的同比增长率、折扣率、连带率是动态参数,可以根据预测天数调整成对应的同期数据。

相关推荐
IT·小灰灰3 小时前
腾讯HY2.0 Think推理模型深度解析:技术突破、应用场景与实践指南
开发语言·人工智能·python·深度学习·神经网络·算法·数据分析
小王毕业啦4 小时前
2008-2023年 全国统一大市场发展水平
大数据·人工智能·数据挖掘·数据分析·数据统计·社科数据·实证数据
宝桥南山5 小时前
Azure - 尝试使用一下Kusto Query Language(KQL)
sql·microsoft·微软·database·azure·powerbi
李慕婉学姐5 小时前
【开题答辩过程】以《基于Hadoop的医生相关数据分析与可视化及医生推荐系统》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
大数据·hadoop·数据分析
IT·小灰灰7 小时前
DeepSeek-V3.2:开源大模型的里程碑式突破与硅基流动平台实战指南
大数据·人工智能·python·深度学习·算法·数据挖掘·开源
一个散步者的梦17 小时前
一键生成数据分析报告:Python的ydata-profiling模块(汉化)
python·数据挖掘·数据分析
语落心生18 小时前
餐饮供应链的数仓设计思考 (七) 数据产品与应用创新方案
数据分析
语落心生18 小时前
餐饮供应链的数仓设计思考 (六) 数据分析与业务预测方案
数据分析
数据智研21 小时前
【数据分享】腾格里沙漠空间矢量范围
大数据·信息可视化·数据分析