零售数据分析的概念

零售行业核心指标

运营类业务指标
业绩指标

四核指标

三效指标

拓展指标

商品类业务指标
动销指标

库存指标


关联指标

会员类业务指标
存量指标

新增指标

复购指标

流失指标

项目背景
项目中为一家零售服装公司的数据集,公司有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)
单据数的同比增长率、折扣率、连带率是指同期的数据,与预测的时间窗口必须一致。单据数的同比增长率、折扣率、连带率是动态参数,可以根据预测天数调整成对应的同期数据。