上篇文章我们已经初步了解了筛选上下文的定义与生成方式,以及初始筛选器等内容。为了更好地掌握筛选上下文,那么本篇文章将介绍筛选器的相关内容,主要就是介绍筛选器的表示形式与在表间关系上的传递过程,并简单介绍下两种计值上下文的调用方式等等。


  标准筛选器、固化筛选器以及筛选器组合都是用元组来表示的,元组与表很相似,表可以转化成元组,但元组并不能转化成表,像CALCULATE函数的内部筛选器就是用表来表示筛选器元组。在一个筛选器元组中,相同行上不同列的值是且的关系,不同行上的值是或的关系,这与Excel中高级筛选的条件区域是非常相似的。

  我们先来看一下标准筛选器的表示形式,如下图所示:

  所谓的标准筛选器指的是只筛选单个列的筛选器,上面这个标准筛选器筛选的内容就是A产品或B产品或C产品,用伪代码可以表示成如下:

产品名称 = A产品 || 产品名称 = B产品 || 产品名称 = C产品

  下面再来看一下固化筛选器的表示形式,如下图所示:

  像这种筛选多个列的筛选器被称为固化筛选器,固化筛选器与标准筛选器非常相似,但由于固化筛选器具有多个列,所以在与别的筛选器进行交互的时候略有不同。上面这个固化筛选器筛选的内容就是红色的A产品、黄色的B产品以及蓝色的C产品,用伪代码可以表示成如下:

产品名称 = A产品 && 产品颜色 = 红色 ||
产品名称 = B产品 && 产品颜色 = 黄色 ||
产品名称 = C产品 && 产品颜色 = 蓝色

  下面来看一下筛选器在表间关系里的传递过程。筛选器在表间关系里的传递过程的理解方式有两种,一种是依靠扩展表原理,另一种则是依靠筛选器的复制,其中第一种方式是最常见且最重要的,而第二种方式则是作为补充,在弱关系上才会用到,例如多对多关系、双向筛选关系等等,但也可以用第二种方式来理解任何关系的筛选传递过程,它是通用的,只是略为繁琐。下面就只介绍第二种方式,第一种方式等我们后续掌握了扩展表原理后再介绍。

  先来看一下要用到的数据与数据模型,如下图所示:

  我把第二种方式的传递过程称为筛选器的复制,这是因为任何列上的筛选器最终都会转化成连接关系的两个字段上的筛选器,当然这只是在效果上等同,原本的筛选器并不会消失,也不会增加新的筛选器。下面我们通过一个小例子来说明这种传递过程:

  首先,先新建一个汇总销售额的度量值,具体的度量值表达式如下:

销售金额 = SUM('订单表'[销售额])

  然后创建一个矩阵视觉对象,把产品表中的产品类别字段放入行字段,并把上面的销售金额度量值放入值字段。结果如下图所示:

  首先,在销售金额度量值开始计算之前就已经存在一个初始的筛选器了,那就是矩阵的行标签,而矩阵的行标签使用了产品表中的产品类别字段,也就是说在产品表的产品类别列上存在一个筛选器,这个筛选器筛选的内容就是当前行标签所显示的内容。其次,在销售金额度量值中使用了SUM函数去汇总订单表中的销售额字段。那么现在,筛选器位于产品表的产品类别列上,要汇总的值位于订单表的销售额列上,且产品表与订单表间的关系为一对多关系,所以行标签所提供的筛选器能够顺着关系箭头的指向去筛选订单表,这就涉及到了筛选器在表间关系上的传递过程。我们以上图中智能设备对应的销售金额为例,逐步介绍199这个值的计算过程,具体如下:

  1. 产品表与订单表上连接关系的字段分别为各自表的产品名称字段

  2. 现有的筛选器为:’产品表’[产品类别] = 智能设备

  3. 上述筛选器在效果上转化成产品表的产品名称列上的筛选器,筛选的内容如下:

    '产品表'[产品名称] = 智能手表 || '产品表'[产品名称] = 智能手环 || '产品表'[产品名称] = VR眼镜

  1. 把产品表的产品名称列上的筛选器复制到订单表的产品名称列上,筛选内容变为:

    '订单表'[产品名称] = 智能手表 || '订单表'[产品名称] = 智能手环 || '订单表'[产品名称] = VR眼镜
  2. 经筛选后得到订单表的筛选上下文,如下图所示:

  3. 销售金额度量值在上述的筛选上下文中计值,将把销售额列上的可见值汇总起来,最终得到汇总值:199

  通过上面这个小例子,我们应该就能掌握这种筛选器在表间关系上的传递过程,这种传递方式的理解虽然主要应用在弱关系上,是对不能使用扩展表原理时的一种补充,但它却是通用的,可以用它来理解任何关系上的筛选传递过程,这对初学者来说应该算是比较友好的一种理解方式了。等后面我们掌握了扩展表原理之后,这种理解方式就很少用到了,现在刚好可以用来过渡。


  最后,再简单介绍一下两种计值上下文的调用方式。筛选上下文与行上下文是同时存在的,所以我们要搞清楚怎样写代码是在调用筛选上下文,怎样写代码是在调用行上下文。其实这里面的区别很简单,如果引用的是表,那肯定是使用的筛选上下文。如果引用的是列,那只需看列引用外有没有套上别的函数,如果套了函数那么就是使用的筛选上下文,如果没有套函数,是直接引用的列,那么就是使用行上下文。当然,这并不是绝对的,但也就只在极少部分情况时才会违背这个规律。


  DAX系列文章中涉及到的案例文件,均已上传到QQ群:344353627,若有需要,可自行加群获取。

  加入Q群