本篇文章将简单介绍一些有益的书写规范,以及DAX中的绝大部分基础函数,这些基础函数都是从Excel中继承过来的,与DAX原理的相关度比较低,易于学习。如果你已经对Excel公式很熟悉,那么简单过一遍即可,否则建议熟悉完基础函数后再进行后续的学习。
下面先来看一下DAX中各个对象的书写规范:
- 各个对象的名称不区分大小写,标点符号必须为英文状态下的符号
- 表的引用方法:’TableName’
- 度量值的引用方法 :[MeasureName],虽然把表名带上也不会出错,但非常不建议度量值带表名
- 列的引用方法:
- 完全限定性写法 :’TableName'[ColumnName]
- 非限定性写法 :[ColumnName],只适用于存在行上下文的环境
- 字符串的表示方法:"String"
- 注释符号:
- //
- /*………*/
- 快捷键:Ctrl+/
从上面的书写规范中可以看出,度量值与列的引用方法都是可以带表名或不带表名的,若两者均带上表名或均不带表名,那么在一个比较复杂的DAX表达式中,将很难判断哪个是度量值引用、哪个是列的引用,这样就给我们阅读DAX表达式带来了不必要的麻烦。所以我们有一个约定俗成的书写规则,即:度量值的引用不带表名,而列的引用则带表名。这样,我们就可以轻松判断出两者的类别,能够把精力更专注于表达式的逻辑中。
其次,我们应该使用一种便于阅读DAX表达式的格式化风格,在介绍格式化的风格之前,先来看一下未格式化与格式化后的DAX表达式对比:
// 这是未格式化的DAX表达式:
SUMX(SUMMARIZE('T3销售','日期表'[Date],'T0大类'[T0大类K]),IF([Sales]<>BLANK(),VAR CurrentDay = '日期表'[Date]
VAR LastDay = LASTNONBLANK(FILTER(ALL('日期表'[Date]),'日期表'[Date]<CurrentDay),[Sales]) RETURN CALCULATE([Sales],LastDay)))
// 这是格式化后的DAX表达式:
SUMX (
SUMMARIZE ( 'T3销售', '日期表'[Date], 'T0大类'[T0大类K] ),
IF (
[Sales] <> BLANK (),
VAR CurrentDay = '日期表'[Date]
VAR LastDay =
LASTNONBLANK (
FILTER ( ALL ( '日期表'[Date] ), '日期表'[Date] < CurrentDay ),
[Sales]
)
RETURN
CALCULATE ( [Sales], LastDay )
)
)
我们先不管上面的DAX表达式的逻辑,只从易于阅读的角度来观察。那么在上面的对比中我们可以发现,未格式化的DAX表达式是不易于阅读的,它的各个函数以及参数均不容易区分,而格式化后的DAX表达式则没有这个缺点,是易于阅读的。因此,我们应该统一使用一种便于阅读的格式化风格。格式化风格之间的差异并不重要,只要这种格式化风格是便于你自己阅读你所写的DAX表达式的即可。
虽然格式化风格可以多种多样,但为了方便与各个DAX的学习者交流,我们一般都是采用两位意大利大师所给出的格式化规则,这也是DAX Studio所采用的规则,具体如下:
- 切勿使用缩短的CALCULATE语法
- 这意味着不要使用[measure](filter)而是使用CALCULATE([measure],filter)
- 总是在括号’(’和’)’前加一个空格
- 始终在表达式中的任何操作数和运算符之前放置一个空格
- 如果必须将表达式拆分成更多行,则运算符是换行符中的第一个字符
- 拆分为更多行的表达式中的函数调用必须始终位于新行中,并在前面加上运算符
- 切勿在表名和列名之间放置空格
- 如果需要,仅对表名使用单引号
- 因此,如果表名没有空格,请省略单引号
- 切勿将表名称用于度量
- 始终使用表名称作为列引用
- 即使您在表中定义计算列
- 如果在同一行中,请始终在参数前放置一个空格
- 仅当函数具有单个参数而不是函数调用时,才编写函数内联
- 如果函数调用具有2个或更多参数,则始终将参数放在新行上
- 如果函数写在更多行上:
- 左括号’(’在函数调用的同一行
- 参数以换行符开头,从函数调用的开头缩进4个空格
- 右括号与函数调用的开始对齐
- 分隔两个参数的逗号在前一个参数的同一行(之前没有空格)
规则来源:https://www.sqlbi.com/articles/rules-for-dax-code-formatting/
下面介绍一些常用的基础函数:
- 时间日期函数:
函数 | 作用 |
---|---|
DATE | 返回日期时间格式的日期值 |
DATEVALUE | 将文本格式的日期转换为日期时间格式 |
EDATE | 返回按指定月数平移后的日期 |
EOMONTH | 返回指定月数平移后的月份的最后一天 |
YEAR | 返回日期的年份 |
QUARTER | 返回日期的季度 |
MONTH | 返回日期的月份 |
DAY | 返回日期的天数 |
WEEKDAY | 返回当前日期对应的星期数,ReturnType=2 以周一为起始 |
WEEKNUM | 返回当前日期位于一年中的周数,ReturnType=2 以周一为起始 |
TIME | 将数字形式的小时、分钟和秒转换为日期时间格式 |
TIMEVALUE | 将文本格式的时间转换为日期时间格式 |
NOW | 返回当前日期和时间 |
TODAY | 以日期时间格式返回当前日期 |
HOUR | 返回时间的小时 |
MINUTE | 返回时间的分钟 |
SECOND | 返回时间的秒 |
- 文本函数
函数 | 作用 |
---|---|
FIND | 查找一个字符串在另一个字符串里的起始位置,区分大小写,不支持通配符 |
SEARCH | 查找一个文本字符串在另一个字符串里的起始位置,不区分大小写,支持通配符 |
LEFT | 从一个字符串的左边开始提取字符 |
RIGHT | 从一个字符串的右边开始提取字符 |
MID | 从一个字符串的任意位置开始提取字符 |
LEN | 返回字符串的长度 |
CONCATENATE | 字符串连接 |
REPLACE | 将字符串的某些字符用另一个字符串代替 |
SUBSTITUTE | 用一个字符串去替换另一个字符串的特定字符 |
LOWER | 将字符串全部小写 |
UPPER | 将字符串全部大写 |
TRIM | 删除字符串前后多余的空格 |
VALUE | 将文本型数字转换为数值型数字 |
- 数学函数
函数 | 作用 |
---|---|
ABS | 返回绝对值 |
DIVIDE | 安全除法,在分母为0时可返回替代结果,默认空值 |
EXP | 返回自然常数 e 的给定数字次方 |
LN | 自然对数 |
LOG | 返回指定底数的对数 |
LOG10 | 返回以十为底的对数 |
MOD | 返回指定数字被整除后的余数 |
POWER | 返回提升到幂的数字的结果 |
SQRT | 返回给定数字的平方根 |
FACT | 返回给定数字的阶乘 |
RAND | 返回一个大于等于 0 且小于 1 的均匀随机数 |
RANDBETWEEN | 返回指定数字之间的随机数 |
PI | 返回圆周率 |
- 转换函数
函数 | 作用 |
---|---|
CONVERT | 将表达式转换为指定的数据类型,可转换为整数,双精度,字符串,布尔值,货币,日期时间类型 |
INT | 将表达式转换为整数(向下舍入) |
TRUNC | 通过删除数字的小数或小数部分将数字截断为整数 |
ROUND | 将数字四舍五入为指定的数字 |
DATE | 返回日期时间格式的日期值 |
DATEVALUE | 将文本格式的日期转换为日期时间格式 |
TIME | 将数字形式的小时、分钟和秒转换为日期时间格式 |
TIMEVALUE | 将文本格式的时间转换为日期时间格式 |
VALUE | 将文本型数字转换为数值型数字 |
FORMAT | 将值转换为指定数字格式的文本 |
- 逻辑函数
函数 | 作用 |
---|---|
IF (condition,true,false) | 条件判断语句 |
SWITCH | 根据表达式的值返回不同的结果。 |
AND() | 逻辑与 |
OR () | 逻辑或 |
NOT () | 逻辑非 |
TRUE () | 逻辑真 |
FALSE () | 逻辑假 |
IFERROR | 判断是否出错 |
- 信息函数
函数 | 作用 |
---|---|
ISBLANK | 检查值是否为空 |
ISEMPTY | 检查表是否为空 |
ISERROR | 检查值是否为错误 |
ISLOGICAL | 检查是否为逻辑值 |
ISNONTEXT | 检查是否为非文本 |
ISNUMBER | 检查是否为数值 |
ISTEXT | 检查是否为文本 |
- 聚合函数
函数 | 作用 |
---|---|
SUM | 求和 |
AVERAGE | 求平均 |
MAX | 最大值 |
MIN | 最小值 |
COUNT | 对数值计数 |
COUNTA | 对非空数据计数 |
COUNTROWS | 计算表的行数 |
COUNTBLANK | 计算列中的空值个数 |
DISTINCTCOUNT | 计算去重后的数据个数 |
STDEV.P | 求总体标准差 |
STDEV.S | 求样本标准差 |
VAR.P | 求总体方差 |
VAR.S | 求样本方差 |
PRODUCT | 返回列中的数的乘积 |
DAX系列文章中涉及到的案例文件,均已上传到QQ群:344353627,若有需要,可自行加群获取。