
上节课的ALL函数在今后的课程上还会经常拿出来讲,大家需要慢慢吸收。本节课的知识,只要你遵循数据库原理,表格都是1对多关系,1端主键不为空不重复,且1端主键元素数大于等于多端外键的元素去重后的个数(数据库:实时参照完整性),可以当本节课就是在浪费时间。只是《The Definitive Guide to DAX》举了例子,国内就有人依此抬扛,并且组建了DAX原理大军。

图1-9-1
如图1-9-1,1端表姓名有3个人,多端表姓名有4个人,这是1对多,但它是典型的实时参照不匹配。接下来我们主要是在这种情况下举例:













大家都知道聚合函数CountRows参数是一张表,之前我们可以用Filter筛选表或ALL全选表,通过缩小或扩大表的范围后放到CountRows(表)里面计算行数。
如果我们只想计算某个表中的某个列它去重之后的行数。这个时候我们就用到了Values或DISTINCT。我们以实时参照不匹配举例:



如上图,当矩阵行标题是多端表中的姓名时,多端不能筛选一端,所有度量值没有筛选功能,但是由于Values检测到实时参照不匹配的情况,多了一个空行,它的总行数就是4,而DISTINCT的总行数就是3。

如上图,当矩阵行标题是一端表中的姓名时,可以筛选了,Values检测到实时参照不匹配的情况,多了一个空行,它的总行数就是4,筛选后每个人都是1,而DISTINCT的总行数就是3。
当出现实时参照不匹配的时候,如果我们需要不显示这个空行,就会用到DISTINCT(列)。
开始时就告诉大家,ALL函数以后要讲的地方多了去了,这节课我们就再讲讲,其它ALL(列)与Values(列)只是功能不同,前者是全选,后者是去重。但是,它们有一个共同点:都会考虑是否出现了实时参照不匹配情况,如果出现了,就会在你all(一端表[列名])时,出现空行。
我们可以使用《火力全开》笔记第8课讲的ALLNOBLANKROW函数处理空行问题。
ALL(列) 与 ALLNOBLANKROW(列)
Values(列) 与 DISTINCT(列)
左边函数会检测空行,右边函数会忽略检测。
我们写两个度量值:
all行数 = countrows(all('某女男朋友'[姓名]) )
ALLNOBLANKROW行数 = countrows(ALLNOBLANKROW('某女男朋友'[姓名]) )

如上图所示,我们使用卡片图展示两个度量值的结果,all行数 =4,因为它检测到了实时参照不匹配,产生了一个空行。而ALLNOBLANKROW行数忽略了检测,返回的就是3。
这里给大家讲一个故事:2020年10月7日我20岁生日当天晚上,DAX原理之父某枫讲师1分钟内在我的powerbI所有视频下留言,称我不讲原理是坑人误导人。后来我看了一下他讲的内容,完全是看完《The Definitive Guide to DAX》着魔了,书中确实是这样讲的,但是在实际工作中,一对多关系,是要尊寻实际参照完整性的,没有意义的事情我何必在新手小白的课程中反复强调呢?数据库的基础知识很重要,不懂数据库,必会走火入魔。
并不是所有事都可以拿来抬扛,我曾经在知乎上给部分讲师讲过一个道理:
假设有一个叫吴刷的人,正在被警方围剿,这时他突然原地起飞,飞出地球之外。注意细节,他是原地起飞。高度不影响经纬度。那么他这种行为,在没有改变经纬度的情况算不算逃跑呢?如果是罗老师讲法,我们可以研究探讨。如果今天要执行抓捕行动,你问领导遇到这种情况,我可不可以采取必要措施,领导可能会说你科幻电影看多了。

《The Definitive Guide to DAX》上面的解释翻译成中文:对表去重但是不考虑空行。
刚才你们是否发现了一个问题,Values(1端表[列]) 才会有空行的问题,Values(多端表[列])没有空行问题,因为检测实时参照不匹配的问题,是从一端检测多端的。
我们只会将DISTINCT函数用到多端表上,一端特点是什么?答:主键不为空不重复。那么你用DISTINCT(1端表)和直接用这张1端表有什么区别呢?根本就没有重复,谈何去重?既然我们不应用到一端,又谈何检测实时参照不匹配呢?
这就是喜欢英语和喜欢数学的区别,拥有逻辑思维的人,不会全信任何书籍,要自己测试,依据事实说话。

你看出现空行了吧?同理,ALL(表)也会遇到同样问题,我们会使用ALLNOBLANKROW(表)处理,详见《火力全开》笔记第8课
(指定多列去重我们以后再讲,这两个函数只支持一个参数,不支持指定多列去重)