动态多条件筛选前10名

题目:


现有一个班级共50人,成绩明细数据如上图,需要筛选出[语文]和[数学]同时前10名的人。

解法:

多条件筛选问题,如果是要筛选出固定值,比如语文和数学都>90,那么直接一步= Table.SelectRows(源,each [语文]>90 and [数学]>90)筛选即可。
但是现在要筛选的是动态值,你并不知道前10名到底要多少分。当然你也可以想办法把第11名的分数求出来,然后和上面的方法一样,但是这样好像比较麻烦,看看有没有其他思路?
本题是要双条件,我们先来看看单条件怎么解?
筛选出[语文]前10名的人,那么可以先按照[语文]降序排列,然后Table.FirstN取出前10个。
那么现在双条件,相当于把原表复制成两份,一张取[语文]的前10名,另一张取[数学]的前10名,然后取两张表的交集即可。
但是PQ中并没有取表交集的函数,所以需要先将表转为list,然后使用List.Intersect取list的交集,最后再还原成表。

let
    top = (x)=>Table.ToRecords(Table.FirstN(Table.Buffer(Table.Sort(源,{x, 1})),10)),
    源 = Excel.CurrentWorkbook(){[Name="成绩"]}[Content],
    前10 = Table.FromRecords(List.Intersect({top("语文"),top("数学")}))
in
    前10

4 Replies to “动态多条件筛选前10名”

  1. 上午好,自定义函数中加Table.Buffer使自定义函数功能加大很多。就是不知道数据量大的时候,内存处理表的效率。

    1. 对于需要重复调用的步骤,使用Table.Buffer转为内存表可以大幅提升效率。
      但这里的Table.Buffer不是为了提速,而是因为用了Table.Sort排序后表为不稳定状态,避免后续出现各种问题。
      案例中用了Table.FirstN+Table.Sort,但后来想了一下其实用Table.MaxN就好了,第一步改成top = (x)=>Table.ToRecords(Table.MaxN(源,x,10))。

  2. 刚学,试了一下可以。选出语文数学的前10名,然后筛选看是否同时包含

    bb=List.MaxN(更改的类型[语文],10),
    cc=List.MaxN(更改的类型[数学],10),
    aa=Table.SelectRows(更改的类型,each List.Contains(bb,_[语文]) and List.Contains(cc,_[数学]))

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注