DAX 如何根据切片器选择,按共同的 Year 和 Location 组合计算平均值?
可以分别取得当前行 Label 和切片器所选 Label 的 (Year, Location) 组合,用 INTERSECT 求出交集,再通过多列 TREATAS 将交集用于平均值计算。两个重叠平均值使用同一组交集,分别计算当前行 Label 和切片器所选 Label 的平均值。
现有的 Selected Label Average Overlap 也需要调整:分别判断年份和地点是否存在,无法保证它们作为一个组合同时存在。
为什么分别过滤 Year 和 Location 会算错?
例如,B 存在 (2023, LocationB),A 存在 (2023, LocationA)。虽然年份相同,但这两个组合并不重叠。
原公式分别使用:
Data[Year] IN VALUES(Data[Year])
Data[Location] IN VALUES(Data[Location])
只要年份和地点分别存在于各自的集合中,就可能保留不匹配的记录。计算时需要保留两列之间的配对关系。
原来的 Label Average Overlap 还有三个问题:
VALUES(Data[Year])只返回年份,丢失了 Location。Data[Parent]没有出现在给定的表结构中;按题意,应比较Data[Label]。- 返回部分使用
Data[Label] = SlicerLabel,计算的会是所选 Label,而不是当前行 Label。
计算当前行的 Label Average Overlap
以下写法适用于题目中的模型:Label_List 与 Data 不建立关系,切片器使用 Label_List[Label],可视化行使用 Data[Label]。将代码创建为度量值:
Label Average Overlap =
VAR HasSingleSelection =
HASONEVALUE(Label_List[Label])
VAR HasSingleRowLabel =
HASONEVALUE(Data[Label])
VAR SlicerLabel =
SELECTEDVALUE(Label_List[Label])
VAR RowPairs =
SUMMARIZE(
Data,
Data[Year],
Data[Location]
)
VAR SelectedPairs =
CALCULATETABLE(
SUMMARIZE(
Data,
Data[Year],
Data[Location]
),
REMOVEFILTERS(Data[Label]),
Data[Label] = SlicerLabel
)
VAR CommonPairs =
INTERSECT(RowPairs, SelectedPairs)
RETURN
IF(
HasSingleSelection && HasSingleRowLabel,
CALCULATE(
AVERAGE(Data[Value]),
KEEPFILTERS(
TREATAS(
CommonPairs,
Data[Year],
Data[Location]
)
)
),
BLANK()
)
RowPairs 从当前行的筛选上下文中取得组合。SelectedPairs 清除当前行的 Label 筛选,取得切片器所选 Label 的组合,同时保留其他筛选条件。
返回部分保留了当前行 Label 的筛选,因此算出的是当前行在共同组合上的平均值。
计算 Selected Label Average Overlap
第二个度量值使用相同的交集,但在求平均值时,将 Label 筛选切换为切片器所选的值:
Selected Label Average Overlap =
VAR HasSingleSelection =
HASONEVALUE(Label_List[Label])
VAR HasSingleRowLabel =
HASONEVALUE(Data[Label])
VAR SlicerLabel =
SELECTEDVALUE(Label_List[Label])
VAR RowPairs =
SUMMARIZE(
Data,
Data[Year],
Data[Location]
)
VAR SelectedPairs =
CALCULATETABLE(
SUMMARIZE(
Data,
Data[Year],
Data[Location]
),
REMOVEFILTERS(Data[Label]),
Data[Label] = SlicerLabel
)
VAR CommonPairs =
INTERSECT(RowPairs, SelectedPairs)
RETURN
IF(
HasSingleSelection && HasSingleRowLabel,
CALCULATE(
AVERAGE(Data[Value]),
REMOVEFILTERS(Data[Label]),
Data[Label] = SlicerLabel,
KEEPFILTERS(
TREATAS(
CommonPairs,
Data[Year],
Data[Location]
)
)
),
BLANK()
)
TREATAS 中目标列的顺序必须与 CommonPairs 一致:第一列是 Year,第二列是 Location。
补充两个普通平均值度量值
Label Average =
AVERAGE(Data[Value])
Selected Label Average =
VAR SlicerLabel =
SELECTEDVALUE(Label_List[Label])
RETURN
IF(
HASONEVALUE(Label_List[Label]),
CALCULATE(
AVERAGE(Data[Value]),
REMOVEFILTERS(Data[Label]),
Data[Label] = SlicerLabel
),
BLANK()
)
这里的“全部记录”指当前其他筛选条件下的记录。如果页面还筛选了 Year 或 Location,这两个普通平均值也会受到影响。
用样例数据核对结果
切片器选择 A 时,B 与 A 的共同组合只有:
| Year | Location | B 的 Value | A 的 Value |
|---|---|---|---|
| 2024 | LocationA | 92 | 105 |
| 2025 | LocationA | 94 | 110 |
B 行的两个结果应为:
Label Average Overlap = (92 + 94) / 2 = 93。Selected Label Average Overlap = (105 + 110) / 2 = 107.5。
按给定数据逐项计算,完整结果如下,循环小数保留两位:
| Label | Label Average | Label Average Overlap | Selected Label Average | Selected Label Average Overlap |
|---|---|---|---|---|
| A | 102.6 | 102.6 | 102.6 | 102.6 |
| B | 92 | 93 | 102.6 | 107.5 |
| C | 87 | 85 | 102.6 | 105 |
| D | 101.33 | 102 | 102.6 | 101.5 |
| E | 110.33 | 112 | 102.6 | 95 |
| F | 97.4 | 97.67 | 102.6 | 99.33 |
这些数值根据样例数据计算得出,并非 Power BI 环境中的运行测试结果。
使用时需要注意什么?
- 切片器应开启单选。上面的公式在筛选上下文不能确定唯一所选 Label 时返回
BLANK()。 - 没有共同组合时,没有记录参与平均,结果为
BLANK()。 - 重叠度量值要求当前上下文只有一个
Data[Label]。包含多个 Label 的总计行会返回空白;如果需要总计,应另行定义总计的业务含义。 - 如果同一 Label 的一个
(Year, Location)组合有多条记录,AVERAGE(Data[Value])会平均全部匹配记录,记录较多的组合权重更大。如果希望每个组合权重相同,需要先按组合聚合,再用AVERAGEX计算。 - 如果可视化行改用单独的 Label 维度表,需要调整清除筛选的位置,否则维度表仍可能限制所选 Label 的数据。
备注:内容仅供参考。
