在 DAX(不是 powerquery)中,根据列删除重复项
In DAX (not powerquery) drop duplicates based on column
在我的 PowerBI 桌面中,我有 table 是根据其他 table 计算得出的,其结构如下:
输入table:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Scott</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Bob</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Ted</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>EDF@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>LMN@QRS.com</td>
</tr>
<tr>
<td>Bill</td>
<td>LMN@QRS.com</td>
</tr>
</tbody>
</table>
现在,我只想保留每封唯一电子邮件的第一条记录。我使用 DAX 的预期输出 table 是:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Scott</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>EDF@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>LMN@QRS.com</td>
</tr>
</tbody>
</table>
我尝试使用 RANKX 和 FILTER,但没有成功。
遗憾的是,这个问题的答案是 DAX 中没有办法引用行相对于 table 中其他行的位置。唯一的选择是使用一些列值进行排序。
我们可以使用现有的两列 table 来获取每封电子邮件的 MAX 或 MIN 名字。所以我们可以像下面这样写一个计算的table,其中T
是输入table,T Unique
是生成的table。
T Unique =
ADDCOLUMNS(
ALL( T[Email] ),
"Firstname",
CALCULATE(
MAX( T[Firstname ] )
)
)
但这不满足要求
要获得所需的结果,我们需要向输入添加一列 table,并带有索引或时间戳。
对于这个例子,我在 Power Query 中使用以下 M 代码添加了一个索引列,它是通过引用原始 table 然后单击添加列 -> 索引列按钮自动生成的
let
Source = T,
#"Added Index" = Table.AddIndexColumn(Source, "Index", 1, 1, Int64.Type)
in
#"Added Index"
所以我得到了 T Index
table.
现在我们可以编写以下计算 table,它使用新列检索每个电子邮件的第一行
T Index Unique =
ADDCOLUMNS(
ALL( 'T Index'[Email] ),
"Firstname",
VAR MinIndex =
CALCULATE(
MIN( 'T Index'[Index] )
)
RETURN
CALCULATE(
MAX( 'T Index'[Firstname ] ),
'T Index'[Index] = MinIndex
)
)
生成请求的 table
在真实案例场景中,添加新列的最佳位置是直接添加到生成输入的代码中 table。
在我的 PowerBI 桌面中,我有 table 是根据其他 table 计算得出的,其结构如下:
输入table:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Scott</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Bob</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Ted</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>EDF@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>LMN@QRS.com</td>
</tr>
<tr>
<td>Bill</td>
<td>LMN@QRS.com</td>
</tr>
</tbody>
</table>
现在,我只想保留每封唯一电子邮件的第一条记录。我使用 DAX 的预期输出 table 是:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Scott</td>
<td>ABC@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>EDF@XYZ.com</td>
</tr>
<tr>
<td>Scott</td>
<td>LMN@QRS.com</td>
</tr>
</tbody>
</table>
我尝试使用 RANKX 和 FILTER,但没有成功。
遗憾的是,这个问题的答案是 DAX 中没有办法引用行相对于 table 中其他行的位置。唯一的选择是使用一些列值进行排序。
我们可以使用现有的两列 table 来获取每封电子邮件的 MAX 或 MIN 名字。所以我们可以像下面这样写一个计算的table,其中T
是输入table,T Unique
是生成的table。
T Unique =
ADDCOLUMNS(
ALL( T[Email] ),
"Firstname",
CALCULATE(
MAX( T[Firstname ] )
)
)
但这不满足要求
要获得所需的结果,我们需要向输入添加一列 table,并带有索引或时间戳。
对于这个例子,我在 Power Query 中使用以下 M 代码添加了一个索引列,它是通过引用原始 table 然后单击添加列 -> 索引列按钮自动生成的
let
Source = T,
#"Added Index" = Table.AddIndexColumn(Source, "Index", 1, 1, Int64.Type)
in
#"Added Index"
所以我得到了 T Index
table.
现在我们可以编写以下计算 table,它使用新列检索每个电子邮件的第一行
T Index Unique =
ADDCOLUMNS(
ALL( 'T Index'[Email] ),
"Firstname",
VAR MinIndex =
CALCULATE(
MIN( 'T Index'[Index] )
)
RETURN
CALCULATE(
MAX( 'T Index'[Firstname ] ),
'T Index'[Index] = MinIndex
)
)
生成请求的 table
在真实案例场景中,添加新列的最佳位置是直接添加到生成输入的代码中 table。