题目:
现有一个班级共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
上午好,自定义函数中加Table.Buffer使自定义函数功能加大很多。就是不知道数据量大的时候,内存处理表的效率。
对于需要重复调用的步骤,使用Table.Buffer转为内存表可以大幅提升效率。
但这里的Table.Buffer不是为了提速,而是因为用了Table.Sort排序后表为不稳定状态,避免后续出现各种问题。
案例中用了Table.FirstN+Table.Sort,但后来想了一下其实用Table.MaxN就好了,第一步改成top = (x)=>Table.ToRecords(Table.MaxN(源,x,10))。
学习了,第一步自定义函数的写法挺好的~
刚学,试了一下可以。选出语文数学的前10名,然后筛选看是否同时包含
bb=List.MaxN(更改的类型[语文],10),
cc=List.MaxN(更改的类型[数学],10),
aa=Table.SelectRows(更改的类型,each List.Contains(bb,_[语文]) and List.Contains(cc,_[数学]))