Power BI----DAX讲解

DAX讲解

  • 一、DAX的使用场景
  • 二、DAX编辑
    • 1.编辑规则
    • 2.编辑语法
  • 三、上下文
    • 1.行上下文
    • 2.筛选上下文
  • 四、DAX函数的分类
    • 1.值函数
    • 2.表函数
  • 五、一些不得不再讲解的函数
    • 1.CALCULATE函数
    • 2.FILTER函数
    • 3.ALL函数
    • 4.FORMAT函数
    • 5.时间智能函数
  • 六、DAX语句

  DAX 是英文 Data Analysis Expression 的缩写,DAX 公式是用作数据分析的,DAX的主要功能正是查询和运算,DAX 查询函数负责筛选出有用的数据集合,然后利用 DAX 的聚合函数执行计算。 如果说度量值是 Power BI 数据建模的灵魂,那么 DAX 就是度量值的灵魂。

一、DAX的使用场景

  说了这么多,可能想问,到底在哪里使用DAX呢,别着急,DAX 可以在 Power BI Desktop 的数据建模和 Power Pivot 中使用,除了可以创建度量值,还可以新建列、新建表(非必要不建议使用,很占内存,如果想增加一列,可以在源数据上,回到查询编辑器里面即PQ增加一列,然后上载到数据模型中使用)。通常在下面界面选择使用DAX:

Power BI----DAX讲解_第1张图片

二、DAX编辑

1.编辑规则

  和其他任何语言一样,DAX也有其特有的编辑规则,虽然不遵守也不影响结果,但会影响代码的可读性,所以尽可能的遵从如下规则:

  • 函数名用大写字母
  • 如果函数只有一个参数,则和函数放在同一行
  • 如果函数具有2个或更多参数,则将每一个参数都另起一行
  • 如果函数及其参数写在多行上:左括号”("与函数在同一行;参数是新行,从该函数对齐位开始缩进4个字符;右括号”)”与函数开头对齐
  • 分隔两个参数的逗号位于前一个参数的同一行
  • 如果必须将表达式拆分为更多行,则运算符是新行中的第一个字符

2.编辑语法

  DAX函数的语法构成如下:

语法:

名称 = 函数名(参数1,参数2…)

示例:

测试度量值 = CALCULATE(
  SUM(draw_data[上周销售总额]),
  FILTER(
    ‘draw_data’,
    [分组]<>“成都2组”
    )
  )

说明:

1.引用数据列用[]括起来,可以带表名,也可以不带
2.数据表用‘’引起来
3.自建的度量值相当于列,引用也是[]括起来

三、上下文

  上下文是要了解的最重要的DAX概念之一。DAX中有两种上下文:行上下文,筛选上下文。我们后面会讲到的度量值和计算列都会是使用这个概念。上下文这个概念非常使人迷惑,我们可以把 “上下文” 理解为 “环境” ,在特定环境下进行的计算。

1.行上下文

示例数据:
Power BI----DAX讲解_第2张图片

  行上下文比较好理解,就是一般是计算。例如:计算上表中的销售额,上下文就是当前表的所有数据。当然行上下文的应用范围不只局限于当前一张表。如果两张表之间建立了关联关系,则通过该关联关系就形成一个跨表的行上下文。类似于excel中的sum。

2.筛选上下文

  筛选上下文则是经过筛选后的结果再进行计算,例如:计算除了6组以外的所有组的销售额,这里环境不是所有数据了,而是经过筛选的新数据环境了。类似与excel中的sumfis()函数等。

四、DAX函数的分类

  DAX函数有好几百个,这里不会一一去介绍说明,只找一些常用且重要的函数进行说明,而且我这里不按照函数的功能去分类讲解,比如:时间函数、聚合函数、逻辑函数、筛选函数等,而是根据函数返回结果,将函数分成值函数和表函数进行讲解。

1.值函数

  顾名思义,值函数就是返回结果是个值,比如SUM、MAX等,这类函数和excel的函数很相似,很容易理解,常见的值函数如下表:

函数 说明 示例
sum、count、average、max、min 常用聚合函数 和excel中的用法一致,不再举例
DISTINCTCOUNT 对列中的非重复值数目进行计数。 DISTINCTCOUNT([分组])
DATE(,, ) 以日期/时间格式返回指定的日期 DATE(2008,1,2):1899是个特殊分割
DATEDIFF(, , ) 返回两个日期之间的间隔边界的计数,频率可以是年月日,季度等 DATEDIFF ( StartDate, EndDate, YEAR )
DATEVALUE(date_text) 将文本格式的日期转换为日期/时间格式的日期。 DATEVALUE(“8/1/2009”)
CALCULATE([, [, [, …]]]) 在已修改的筛选器上下文中计算表达式 CALCULATE(sum([上周销售总额]),all(‘draw_data’[大部]))
CONTAINSSTRING(,) 返回 TRUE 或 FALSE,指示一个字符串是否包含另一个字符串。 CONTAINSSTRING(“abcd”, “bc”)
SWITCH(,, [, , ]…[, ]) 针对值列表计算表达式,并返回多个可能的结果表达式之一 SWITCH([Month], 1, “January”, 2, “February”)
LOOKUPVALUE() 返回满足一个或多个搜索条件所指定的所有条件的行的值 和excel的vlookup很像
IF() 检查条件,如果为 TRUE,则返回一个值,否则返回第二个值。 和excel一样,不做示例
FORMAT(, [, ]) 根据所指定的格式将值转换为文本。 FORMAT( 12345.67, “General Number”)>

2.表函数

  表函数就是返回的是一张表,直接建立度量值会报错,经常和其他聚合函数(值函数)连用,帮助我们创建复杂的计算逻辑的度量值。

函数 说明 示例
CALENDAR(, ) 返回一个表,其中有一个包含一组连续日期的名为“Date”的列 CALENDAR (DATE (2015, 1, 1), DATE (2021, 12, 31))
DATEADD(,,) 返回一个表,此表包含一列日期,日期从当前上下文中的日期开始按指定的间隔数向未来推移或者向过去推移 DATEADD(DateTime[DateKey],-1,year)
ALL( [[,\ [, [,…]]]] )
清除筛选,不单独使用 all(‘draw_data’[大部]):选择所有大部,筛选器也不起作用
FILTER(,)
返回一个表,用于表示另一个表或表达式的子集。 FILTER( ‘draw_data’, [分组]<>“成都2组”)
ADDCOLUMNS(, , [, , ]…)
将计算列添加到给定的表或表表达式。

五、一些不得不再讲解的函数

1.CALCULATE函数

  该函数我觉得是BI中最重要的函数之一,因为其作用是对经过筛选的数据再聚合,而实际中,我们也是需要这样操作,而不是简单的计算。其类似于excel的sumifs()等函数,但可聚合的方式和筛选的条件比Excel强大的多得多。
  换句话说,CALCULATE可以通过它的参数,改变聚合的上下文(环境),然后再在新环境下聚合计算。

CALCULATE([, [, [, …]]])

第一个参数计算表达式,可以执行各种聚合运算
其余参数是一系列筛选条件,可以为空;如果多个筛选条件,用逗号分隔

  该函数的示例,在后续的函数介绍时一起使用,这里不做单独的演示。

2.FILTER函数

  都说CALCULATE函数是必须掌握的函数,而FILTER函数是CALCULATE函数最佳的搭配,所以在介绍完CALCULATE之后,紧接着介绍FILTER函数。

FILTER(

,)
第一个参数是要筛选的表
之后是筛选条件
它是表函数,不能单独使用,必须搭配其他函数使用,做好的搭档是CALCULATE
FILTER函数可以嵌套使用

示例1:计算除了九部之外的所有部门的销售额

除了九部 = CALCULATE(SUM(draw_data[上周销售总额]),FILTER('draw_data',[大部]<>"产品线九部"))

示例2:计算九部、十部之外的所有部门的销售额

除了九十部 = CALCULATE(SUM(draw_data[上周销售总额]),FILTER('draw_data',[大部]<>"产品线九部"),
							FILTER('draw_data',[大部]<>"产品线十部"))

示例3:计算出了九部,剩下的出了10组之外的所有的销售额

嵌套 = CALCULATE(SUM(draw_data[上周销售总额]),
				FILTER('draw_data',and([大部]<>"产品线九部",[分组]<>"成都10组")))

3.ALL函数

ALL( [

| [, [, [,…]]]] )

  顾名思义,all就是所有,即清除所有的筛选,这里的筛选不止是计算时的筛选,还包括所有筛选器,也就是说all可以使得所有筛选器失去作用。all函数不单独使用,多与聚合函数一起使用。

  从上面定义看出,all函数参数可以是单个表,单个列,也可以时多个列。示例如下:

不使用all筛选:

不筛选 = CALCULATE(sum(draw_data[上周销售总额]))

参数为表:

全表 = CALCULATE(SUM(draw_data[上周销售总额]),ALL(draw_data))

当参数为表时,使用该表中的所有字段构建的筛选器都对上述度量值无作用。
参数为列:

单列 = CALCULATE(SUM(draw_data[上周销售总额]),ALL(draw_data[大部]))

当参数为列时,使用该表中的相应的字段构建的筛选器对上述度量值无作用,但其他字段有筛选作用。


  从上面的演示结果清楚的看到,没有筛选时,三个计算结果一致;当用大部做筛选时,后面两个都不收影响;当用小组做筛选时,只有表参数的不受影响。进一步印证了:表参数使得该表中所有字段的筛选器失去作用;列参数只使得相应的列(这里是大部)失去作用,其他字段(小组)还可以筛选。

4.FORMAT函数

FORMAT(, [, ])

  格式转换函数,在任何一个语言中都很重要,所以我们今天讲讲DAX中的格式转换。在BI中,需要转换的就两个方面,一个是日期、时间,需要改变格式,另一个则是数字。下面通过两个方面讲解。
数字

格式参数 输出
0 1235
0.0 1234.6
0% 123456%
0.00% 123456.00%
0.00E+00 1.23E+03
#,## 1,235
#,##0.00 1,234.56
¥#,##0.00 ¥1,234.56
General Number 1234.56
Currency ¥1,234.56
Standard 1,234.56
Percent 123456.00%
Scientific 1.23E+03

  后面几个英文的是BI预定义的数字格式,直接输入相应的英文,就可以输出对应的格式,前面的是自定义的格式。

日期、时间

格式参数 输出 说明
D 1 一位数的日期,
DD 01 两位数的日期
DDD Mon 星期缩写
DDDD Monday 星期全称
AAA 周一 周输出
AAAA 星期一 星期输出
MM 01 两位月份
MMM Jan 月份简称
MMMM January 月份全称
000 1月 数字+月
0000 一月 汉字+月
YYYY 2018 四位年
YYYYMM 201801 年月,无间隔
YYYYMMDD 20180101 年月日,无间隔
General Date 2018/1/1 预定义的日期格式
Long Date 2018年1月1日 长日期,和excel一样
Medium Date 18-01-01 两位年+月日
Short Date 2018/1/1
Long Time 0:00:00
Medium Time 12:00上午
Short Time 0:00

  注意这里有个问题是:数字改变格式后变成字符串,这时候再使用图表会不显示,出现空白的情况,但是表格和卡片图不受影响,所有要是放置条形图、折线图等的数据,格式设置要注意。

5.时间智能函数

  时间可以说是数据分析中最常用的独立变量,工作中也常常会遇到对时间数据的对比分析。假设要计算上年同期的销量,在PowerBI中可以用CALCULATE来写个度量值[上年同期],

= CALCULATE(
  [数量],
  SAMEPERIODLASTYEAR(‘日期表’[日期])
)

  这里SAMEPERIODLASTYEAR就是时间智能函数。

时间智能函数与普通的时间或者日期函数的区别是:

  • 日期函数直接依赖当前行上下文,一般作为新建列使用,比如YEAR函数,提取日期列的年度;
  • 时间智能函数会重置上下文,一般新建度量值时使用,可以快速移动到指定区间

  在PowerBI中,目前共有33个时间智能函数,这里不在一一介绍,讲解几个常用的说明:

DATEADD

DATEADD(,,)
说明:返回一个表,此表包含一列日期,日期从当前上下文中的日期开始按指定的间隔数向未来推移或者向过去推移
其频率参数有year、quarter、month、day

示例:

# 返回上月的利润额
上月利润额 = CALCULATE('cj_bysales'[当月利润额],DATEADD(cj_bysales[月份],-1,MONTH))
# 返回上年的利润额
上月利润额 = CALCULATE('cj_bysales'[当月利润额],DATEADD(cj_bysales[月份],-1,YEAR))

  当日期不连续时,该函数会出错,所以计算环比使用其他的思路:

比如:计算占比增量

广告仓储增量 = IFERROR(
	CALCULATE(
		-sum(cj_bysales[FBA费用])/sum(cj_bysales[销售额]),
		FILTER('cj_bysales',[月份]=MAX('cj_bysales'[月份]))
		) - 
	CALCULATE(
		-sum(cj_bysales[FBA费用])/sum(cj_bysales[销售额]),
		FILTER(
			'cj_bysales',
			[月份]=CALCULATE(MAX([月份]),
			FILTER('cj_bysales',[月份]<>max([月份]))
			)
		)
	)
,0)

六、DAX语句

  和其他的语言一样,DAX也可以通过函数构建语句(多条函数的集合),这里只讲解DAX语句中的自定义变量的使用。说简单点就是将表达式的结果存储为命名变量,然后可以将其作为参数传递给其他度量值表达式。 为变量表达式计算结果值后,这些值不会更改,即使在其他表达式中引用该变量。
语法:

度量值名称 = var 参数名=值
  语句块
  return
  
  
说明:

1.变量名不能和模型中现有的表名、字段名相同,也不能使用数字作为第一个字符,不能使用空格
2.语句必须要用return 返回

示例1:

累计利润占比 = var cur_rate=[帕累托利润占比]
	return CALCULATE(
			[帕累托利润占比],
			FILTER(
				ALL('fba_profit_data_processing_result'[分组]),
				[帕累托利润占比]>=cur_rate
			)
		)

示例2:计算同比数据

# 多个度量值创建
SalesAmount = SUM(SalesTable[SalesAmount])  #当期销售额
SalesAmount PreviousYear =
    CALCULATE([SalesAmount ],
    SAMEPERIODLASTYEAR(Calendar[Date])
    )  # 上期销售额
YoY = 
    IF([SalesAmount] ,  
        DIVIDE(([SalesAmount][SalesAmount PreviousYear]), [SalesAmount]),
        [SalesAmount]
    )   # 计算同比

# 使用变量创建

YoY = VAR Sales = SUM(SalesTable[SalesAmount])  
	  VAR SalesLastYear = CALCULATE(SUM(SalesTable[SalesAmount]), SAMEPERIODLASTYEAR('Calendar'[Date]))
    return if(Sales, DIVIDE(Sales – SalesLastYear, Sales))


  通过上面例子2可知,不用DAX语句,也可实现相应的计算,DAX语句只是减少相应的度量值,提高语句的可读性,同时由于没有中间量的计算,所以效率更高。

  
  
最后,给大家官网的连接,DAX官网,有需要直接官网查找。

你可能感兴趣的:(Power,BI,Power,BI,DAX函数)