博客:www.jiaopengzi.com

焦棚子的文章目录

请点击下载附件

一、背景

某天在和那还是叫我大铁吧 交流关于季度&月度同时展示的问题,感概中国式报表真的需求很微妙。

下面来看看到底是什么。

A、效果图

B、动态效果

[video width="852" height="608" mp4="https://jiaopengzi.com/wp-content/uploads/2020/03/129_2.mp4"][/video]

接下来我们用三种度量的写法来说明。

方法3由那还是叫我大铁吧 提供,我们感谢他。

二、数据源

1、日期表:calendar

因为是日期时间维度的不同展现,都围绕着日期表做文章,所以建立一个合适的日期表很重要。

个人喜欢用pq生成日期表code如下:

let
date_start=#date(2018, 1, 1),//开始日期
date_end=#date(2019, 12, 31),//结束日期
count=Duration.Days(date_end-date_start),//间隔天数
calendar = #table
(
type table
[
dates=date
,year=Int64.Type
,month=Int64.Type
,day=Int64.Type
,year_m=Int64.Type
,quarter=Int64.Type
,year_q=Int64.Type
,weeknumber=Int64.Type
,weekday=Int64.Type
,weekus=text
,weekcn=text
,weekcna=text
,M=text
,YM=text
,Q=text
,YQ=text
]
,List.Transform({0..count},(n)=>
let d=Date.AddDays(date_start,n) in
{
d//日期
,Date.Year(d)//年
,Date.Month(d)//月
,Date.Day(d)//天
,Date.Year(d)*100+Date.Month(d)//年月组合
,Date.QuarterOfYear(d)//季度
,Date.Year(d)*100+Date.QuarterOfYear(d)//年季度组合
,Date.WeekOfYear(d,1)//周一开始的一年第几周
,Date.DayOfWeek(d,1)//星期几
,Date.DayOfWeekName(d, "en-US")//星期几英文
,Date.DayOfWeekName(d, "zh-CN")//星期几中文
,Text.End(Date.DayOfWeekName(d, "zh-CN"),1)//星期几简写
,"M"&Date.ToText(d,"MM")
,Date.ToText(d,"Yyy")&"M"&Date.ToText(d,"MM")
,"Q"&Number.ToText(Date.QuarterOfYear(d))
,Date.ToText(d,"Yyy")&"Q"&Number.ToText(Date.QuarterOfYear(d))
}
)
)
in
calendar

2、事实表:data

用pq生成的随机数据(拿到附件后,若数据和文章截图不一样是正常的。)

3、维度表

分别为事实表维度表,以及季度&月度辅助表。

4、关系视图

A、方法1&方法3的关系视图

B、方法2的关系视图

注意:方法2中两条虚线的使用。

三、上DAX

1、基础度量:total

total = SUM(data[value]) 

2、方法1:test0

test0 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR T1 =
SUMMARIZE (
FILTER ( ALL ( 'CALENDAR' ), 'CALENDAR'[MONTH] <= N ),
'CALENDAR'[M],
'CALENDAR'[Q],
'CALENDAR'[MONTH],
'CALENDAR'[QUARTER]
)
VAR T2 =ADDCOLUMNS ( T1, "@QM", IF( N / 3 <= [QUARTER], [M], [Q] ) )//是否显示整季度关键:"<="
VAR T3 =SUMMARIZE ( T2, [@QM] )
VAR TQ =FILTER ( T3, LEN ( [@QM] ) <= 2 )
VAR TM =FILTER ( T3, LEN ( [@QM] ) > 2 )
VAR I =SUM ( 'aux0'[INDEX] )
RETURN
SWITCH (
TRUE ()
, I >= 1&& I <= 4
, CALCULATE (
'Measure'[total]//基础度量
,TREATAS ( TQ, 'CALENDAR'[Q] )
,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[Q] )
,ALL ( 'CALENDAR'[M] )
)
,I >= 5&& I <= 16
, CALCULATE (
'Measure'[total]//基础度量
,TREATAS ( TM, 'CALENDAR'[M] )
,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[M] )
,ALL ( 'CALENDAR'[M] )
)
,BLANK ()
)

3、方法1:test1

test1 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR T1 =
SUMMARIZE (
FILTER ( ALL ( 'CALENDAR' ), 'CALENDAR'[MONTH] <= N ),
'CALENDAR'[M],
'CALENDAR'[Q],
'CALENDAR'[MONTH],
'CALENDAR'[QUARTER]
)
VAR T2 =ADDCOLUMNS ( T1, "@QM", IF( N / 3 < [QUARTER], [M], [Q] ) )//是否显示整季度关键:"<="
VAR T3 =SUMMARIZE ( T2, [@QM] )
VAR TQ =FILTER ( T3, LEN ( [@QM] ) <= 2 )
VAR TM =FILTER ( T3, LEN ( [@QM] ) > 2 )
VAR I =SUM ( 'aux0'[INDEX] )
RETURN
SWITCH (
TRUE ()
, I >= 1&& I <= 4
, CALCULATE (
'Measure'[total]//基础度量
,TREATAS ( TQ, 'CALENDAR'[Q] )
,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[Q] )
,ALL ( 'CALENDAR'[M] )
)
,I >= 5&& I <= 16
, CALCULATE (
'Measure'[total]//基础度量
,TREATAS ( TM, 'CALENDAR'[M] )
,TREATAS ( VALUES ( 'aux0'[QM] ), 'CALENDAR'[M] )
,ALL ( 'CALENDAR'[M] )
)
,BLANK ()
)

4、方法2:test0

test0 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR IQ=MAX('calendar'[quarter])
VAR I =SUM ( 'aux0'[INDEX] )
RETURN
SWITCH (
TRUE ()
, I < IQ
, CALCULATE (
'Measure'[total]//基础度量
,USERELATIONSHIP('calendar'[Q],'aux0'[QM])
,ALL ( 'CALENDAR'[M] )
)
,I<=IQ*3+4&& I >(IQ-1)*3+4&&I<=N+4
, CALCULATE (
'Measure'[total]//基础度量
,USERELATIONSHIP('calendar'[M],'aux0'[QM])
,ALL ( 'CALENDAR'[M] )
)
,BLANK ()
)

5、方法2:test1

test1 =
VAR N =MAX ( 'CALENDAR'[MONTH] )
VAR IQ=MAX('calendar'[quarter])
VAR I =SUM ( 'aux0'[INDEX] )
VAR TF=MOD(N,3)
RETURN
SWITCH (
TRUE ()
, I <= IQ && NOT(TF)
, CALCULATE (
'Measure'[total]//基础度量
,USERELATIONSHIP('calendar'[Q],'aux0'[QM])
,ALL ( 'CALENDAR'[M] )
)
, I < IQ && TF
, CALCULATE (
'Measure'[total]//基础度量
,USERELATIONSHIP('calendar'[Q],'aux0'[QM])
,ALL ( 'CALENDAR'[M] )
)
,I<IQ*3+4&& I >(IQ-1)*3+4 && TF
, CALCULATE (
'Measure'[total]//基础度量
,USERELATIONSHIP('calendar'[M],'aux0'[QM])
,ALL ( 'CALENDAR'[M] )
)
,BLANK ()
)

6、方法3:test0

test0 =
VAR FindQ =FIND ( "Q", SELECTEDVALUE ( aux0[QM] ),, 0 ) //是否存在Q
VAR DQ =CALCULATE (MIN ( 'calendar'[Q] ),FILTER ( 'calendar', [Q] = SELECTEDVALUE ( 'calendar'[Q] ) ) ) //当前季度
VAR DM =CALCULATE (MIN ( 'calendar'[M] ),FILTER ( 'calendar', [M] = SELECTEDVALUE ( 'calendar'[M] ) )) //当前月份
VAR DQMinMonth =CALCULATE ( MIN ( 'calendar'[M] ), FILTER ( ALL ( 'calendar' ), [Q] = DQ ) ) //当前季度最小月份
VAR RQ =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) = 2 )//季度
VAR RM =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) > 2 )//月
RETURN
SWITCH (
TRUE ()
,FINDQ > 0&& SELECTEDVALUE ( 'aux0'[QM] ) < DQ
, CALCULATE (
SUM ( DATA[VALUE] )
,TREATAS ( RQ, 'calendar'[Q] )
,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[Q] )
,ALL ( 'calendar'[M] )
)
,FINDQ = 0&& SELECTEDVALUE ( aux0[QM] ) <= DM&& SELECTEDVALUE ( aux0[QM] ) >= DQMINMONTH
, CALCULATE (
SUM ( DATA[VALUE] )
,TREATAS ( RM, 'calendar'[M] )
,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[M] )
,ALL ( 'calendar'[M] )
)
   ,BLANK ()
)</code></pre>


7、方法3:test1

test1 =
VAR TF=MOD(AVERAGE('calendar'[month]),3)//季度月末显示季度or月度
VAR FindQ =FIND ( "Q", SELECTEDVALUE ( aux0[QM] ),, 0 ) //是否存在Q
VAR DQ =CALCULATE (MIN ( 'calendar'[Q] ),FILTER ( 'calendar', [Q] = SELECTEDVALUE ( 'calendar'[Q] ) ) ) //当前季度
VAR DM =CALCULATE (MIN ( 'calendar'[M] ),FILTER ( 'calendar', [M] = SELECTEDVALUE ( 'calendar'[M] ) )) //当前月份
VAR DQMinMonth =CALCULATE ( MIN ( 'calendar'[M] ), FILTER ( ALL ( 'calendar' ), [Q] = DQ ) ) //当前季度最小月份
VAR RQ =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) = 2 )//季度
VAR RM =FILTER ( VALUES ( 'aux0'[QM] ), LEN ( [QM] ) > 2 )//月
RETURN
SWITCH (
TRUE ()
,FINDQ > 0 && SELECTEDVALUE ( 'aux0'[QM] ) <= DQ&& NOT(TF)
, CALCULATE (
SUM ( DATA[VALUE] )
,TREATAS ( RQ, 'calendar'[Q] )
,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[Q] )
,ALL ( 'calendar'[M] )
)
,FINDQ > 0 && SELECTEDVALUE ( 'aux0'[QM] ) < DQ
, CALCULATE (
SUM ( DATA[VALUE] )
,TREATAS ( RQ, 'calendar'[Q] )
,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[Q] )
,ALL ( 'calendar'[M] )
)
,FINDQ = 0&& SELECTEDVALUE ( aux0[QM] ) <= DM&& SELECTEDVALUE ( aux0[QM] ) >= DQMINMONTH && TF
, CALCULATE (
SUM ( DATA[VALUE] )
,TREATAS ( RM, 'calendar'[M] )
,TREATAS ( VALUES ( aux0[QM] ), 'calendar'[M] )
,ALL ( 'calendar'[M] )
)
   ,BLANK ()
)</code></pre>

四、总结

1、思维依然是业务转换是筛选上下文;

2、方法1&方法3都是利用TREATAS创建虚拟关系来实现目的;

3、方法2中利用的虚线关系USERELATIONSHIP实现目的,同时方式2兼容PP,目前TREATAS不兼容PP,(更新:office365支持TREATAS)

4、本案例可以衍生如:动态坐标轴、动态维度展示等,可以举一反三的。

彩蛋:季度&月度动态坐标轴

相对比较简单就不单独赘述;见文章素材附件。

[video width="1064" height="924" mp4="https://jiaopengzi.com/wp-content/uploads/2020/03/129_9.mp4"][/video]

by 焦棚子

焦棚子的文章目录

129_Power Pivot&Power BI DAX不同维度动态展示&动态坐标轴的更多相关文章

  1. 123_Power Pivot&Power BI DAX函数说明速查

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 说明 1.基于DAX Studio 2.9.2版本导出整理: 2.DAX Studio网站,及时更新下载,DAX学习利器: ...

  2. 127_Power Pivot&Power BI DAX计算订单商品在库时间(延伸订单仓储费用)

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 前面已经写过一个先进先出的库龄案例,在业务发生又有这样一个需求:先进先出前提,需要按照订单计算每个商品在库时间, ...

  3. 124_Power Pivot&Power BI DAX优化计算最大连续次数

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 最大连续次数或者是最大连续子序列问题,在DAX中如何快速计算呢? 思路 1.N-1:按照INDEX错位 2.ST ...

  4. 设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(2.Azure Functions实战)

    本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品. 主要实战的内容为: 将设备遥测数据上传到物联网中心, 将遥测数 ...

  5. 设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(1.准备工作)

    本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品. 主要实战的内容为: 将设备遥测数据上传到物联网中心, 将遥测数 ...

  6. 122_Power Pivot&Power BI不连续日期的日环比

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 这两天有朋友在交流,dax中使用时间智能函数写日环比,一个 dateadd 就可以了.但是有些业务不是每天都连续 ...

  7. .NET平台开源项目速览(19)Power BI神器DAX Studio

    PowerBI更新频繁,已经有点更不上的节奏,一直在关注和学习中,基本的一些操作大概是没问题,更重要的是注重Power Query,M函数,以及DAX的使用,这才是核心.   上个月研究了DAX的一些 ...

  8. PowerBI开发 第十五篇:Power BI的行级安全

    Power BI支持行级安全(Row-Level Security,RLS)的权限控制,用于限制用户对Dashboard.报表和DataSet的访问.用户浏览的报表是相同的,但是看到的数据却是不同的. ...

  9. 数据可视化之 图表篇(四) 那些精美的Power BI可视化图表

    之前使用自定义图表,每次新打开一个新文件时,都需要重新添加,无法保存,在PowerBI 6月更新中,这个功能得到了很大改善,可以将自定义的图表固定在内置图表面板上了. 添加自定义图表后,右键>固 ...

随机推荐

  1. ROS学习文章

    ros机器人到底有没有必要学习?

  2. 详解 CSS 属性 - position

    postion 属性定义了一个元素在页面布局中的位置以及对周围元素的影响.该属性共有5个值: position: absolute position: relative position: fixed ...

  3. 用Weex开发的V2EX三端app,附探坑总结

    项目地址 git传送门(内附项目预览) Weex环境配置 npm install -g weex npm install -g weexpack # weex客户端的cli npm install - ...

  4. java中接口到底是干什么的,怎么用,深入剖析

    6.总结性深一层次综合剖析接口概念[新手可忽略不影响继续学习] 通过以上的学习, 我们知道,所有定义在接口中的常量都默认为public.static和final.所有定义在接口中的方法默认为publi ...

  5. react和react-dom是什么?

    使用react开发网页的话,我们难免会下载两个包,一个是react,一个是react-dom,其中react是react的核心代码.react的核心思想是虚拟Dom,其实虚拟Dom改变没有那么复杂,简 ...

  6. FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码

    之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...

  7. ABP源码分析 - 服务配置(1)

    比较随意,记录下过程,以便忘了以后重拾. 三个关注点 Program.cs internal static IHostBuilder CreateHostBuilder(string[] args) ...

  8. win内核漏洞提权

    WIN系统溢出漏洞提权 漏洞筛选 在整个提权项目中,前提是拿到webshell. 关于系统的溢出漏洞,我推荐两个项目: https://github.com/chroblert/WindowsVuln ...

  9. python+pytest接口自动化(13)-token关联登录

    在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示 ...

  10. Java进阶 JVM 内存与垃圾回收篇(一)

    JVM 1. 引言 1.1 什么是JVM? 定义 Java Vritual Machine - java 程序的运行环境(Java二进制字节码的运行环境) 好处 一次编译 ,到处运行 自动内存管理,垃 ...