Excel 如何在 DAX 中将一行与其他行进行比较

How to compare one row to others in DAX in Excel

我有这个 table,它有来自其他几个键的外键:

基本上,这个 table 显示哪些学生在哪个模块运行 由哪个老师在哪个学期注册。

我要查询以下内容:

How many students have registered for more than one module run by a given tutor?

它将看起来像这样:

例如,Vasiliy Kuznetsov 运行的两个模块:FunPro 和 NO。如果一个学生同时注册了这两个,他就被算作一个。

我的 sql 导向思维告诉我:计算 student_id 和 tutor_id 相同的所有行。例如,一行中student_id是5,tutor_id是10,第三行也是如此。那我算一个。

我如何使用 DAX 公式做到这一点?

RowCount:=
COUNTROWS( ModuleRegistration )

StudentsWithTwoOrMoreRegistrations:=
COUNTROWS(
    FILTER(
        VALUES( ModuleRegistration[Student_ID] )
        ,[RowCount] >= 2
    )
)

我按位置引用参数,因此函数的第一个参数是 (1),第二个参数是 (2),依此类推。

所以,[RowCount] 是微不足道的。

[StudentsWithTwoOrMoreRegistrations] 有点复杂。 DAX 作为一种函数式语言,最好由内而外地理解。

FILTER() 在 (1) 中采用 table 表达式,并为 (1) 中的每一行计算布尔谓词 (2)。它 returns (1) 中 (2) 计算结果为真的所有行。

我们的 FILTER() 的 (1) 是 VALUES( ModuleRegistration[Student_ID] )。 VALUES() returns 基于当前过滤器上下文的字段中的唯一行(它尊重数据透视表 table 中的切片器和过滤器)。因此,我们将 return [Student_ID] 的唯一列表的一些子集。

我们的 FILTER() 的 (2) 是 [RowCount] >= 2。对于 (1) 中的每个 [Student_ID],我们将评估 [RowCount],检查该学生的次数出现在 ModuleRegistration 中。 [RowCount] 是结合来自数据透视表 table 的筛选器上下文(示例数据透视表中的 [Faculty Name] 字段提供筛选器上下文)和来自 FILTER() (1) 的行上下文进行评估的。因此,它会计算学生在 table 行 table 的 [Faculty Name] 的 ModuleRegistration 中出现的次数。

我们检查 [RowCount] >= 2。

您没有说明您的度量是否需要处理总计,或者您可能希望如何查看。如果您需要更多帮助来使总计按照您喜欢的方式运行,请告诉我。

编辑 总计

您可能希望通过几种方式处理总计。我将假设您想要唯一的学生人数。

StudentsWithTwoOrMoreRegistrations:=
COUNTROWS(
    SUMMARIZE(
        FILTER(
            SUMMARIZE(
                ModuleRegistration
                ,ModuleRegistration[Tutor_ID]
                ,ModuleRegistration[Student_ID]
            )
            ,[RowCount] >= 2
        )
        ,ModuleRegistration[Student_ID]
    )
)

WTF 发生在我们的措施上?

让我们检查一下:

从最里面的 SUMMARIZE() 开始。 SUMMARIZE() 从 (1) 中的 table 向外导航关系,并按 (2)-(N) 中列出的列分组(这些不必来自 (1) 中的 table ,但必须可以通过导航关系访问)。

这相当于 SQL 中的以下内容:

SELECT
    mr.Tutor_ID
    ,mr.Student_ID
FROM ModuleRegistration mr

我们像之前一样在此 table 上使用 FILTER()。 [RowCount] 是根据上面的 SUMMARIZE() 定义的枢轴 table 和 table 中的行的过滤器上下文的组合进行评估的。

现在我们的行上下文不仅仅是一个学生,而是一对学生-导师。当学生从导师那里学习了多个模块时,这对 [RowCount] >= 2。

我们的 FILTER() returns 具有 [RowCount] >= 2 的对。此输出 table 有两个字段,[Tutor_ID] 和 [Student_ID],但我们想从中计算出不同的 [Student_ID]。

因此,我们使用 FILTER() 中的 table 作为外部 SUMMARIZE() 中的 (1)。我们仅按 [Student_ID] 的值分组。然后我们计算这个 table.

的行数

当上下文中只有一个 [Faculty_Name] 时,例如在主元 table 行上,然后我们的内部 SUMMARIZE() 按 [Tutor_ID] 的单个值以及与之关联的任何 [Student_ID] 进行分组。这与我们之前的措施相同。

当我们在上下文中有很多 [Tutor_ID] 时,比如在总计中,那么我们将看到只对每个 [Student_ID] 计数一次的适当行为。