普通视图

就是要用not exists

2026年1月24日 08:30

我知道有一个大表,我也有这个大表其中了一些数据的小表,我需要筛选出除了小表以外的数据,思路非常清晰,但实际上要用Excel里面的SQL实现却好像异常困难。在一些高级数据库里,有特殊的函数实现这个功能,有些用的是except,有些用的是minus,但是Excel里没有。如果可以用except或者是minus,这将意味着可以对大小表全列对比,但是如果用其他方法,只能选取其中一些。刚好我要操作的表有一列刚好是多个列信息的集合,所以用那一列作为标识刚好,但如果我根本没有那一列呢?难道我还得先造一列出来,然后再进行操作吗?无论是用not exists或者not in的方式去进行这种筛选,都只能选取其中的某一列操作。如果是用not in的方式,还得要注意,如果那个小表是空的时候,会导致筛选失效。如果用not exists的方式,则不需要考虑小表是空的情况。

一开始想实现这种功能,我想到的不是这两个,而是用count。先去计算那些有重复项的行,然后针对不同计数结果分别处理。就思路来说很清晰,但就实现来说,很啰嗦。但虽然啰嗦,还是能得出我想要的结果。第一天我用这种计数的方式得到了我想要的结果,但我依然觉得应该有一些更直接一点的方法,于是第2天我就想用not in或者not exists的方式去实现。

not in的方式总算是做到了,但是效率不高,感觉耗时是用计数方式的两倍。in和exists相比,我感觉exists的效率更高,但关键是实际上我使用的是not in和not exist,所以估计还是挺麻烦。虽然就语句来说,不过是多了一个not而已。exists的实现耗费了我不少时间,理论上我的写法没有任何问题,但关键是就会报错。折腾了一个下午都无果。晚上洗澡的时候,我突然想到可能是引用数据简写那里出了状况。在使用not exists子查询的时候。我依然是用经典的a和b简写,但实际上在这个子查询引用的数据里面就曾经出现过a和b。如果某一句查询里面的简写a和b是同一个层次的,没什么问题,但关键是子查询这种操作有递归的感觉,主查询跟子查询不是一个层次。VBA弹出来的报错窗口说某个简写可能指向多个数据。后来我觉得大概是因为之前我就已经有用过a这种简写,层层嵌套之下,exists的子查询不知道我指的到底是哪一层的a。洗完澡以后,我赶紧找文件测试,把主查询的a改为了之前从来没用过的c。果然,not exists子查询通过了!多次测试对比发现not in跟not exists的性能确有区别,not exists会快一点点,但是跟计数相比,好像计数依然是三者之中最快的。从好理解的角度而言,not exists最为复杂,最好理解的我觉得是计数,但是就语句使用的长短而言,not exists和not in最简单的。最后我采用的是not exists的方案,但是not in跟之前计数的方案我都只是把它们注释掉了,没有删除。

如果Excel里面的SQL能与时俱进,我能用一些那些高端的函数,我根本不需要这么大费周折。别人有现成的模块,连个线就能用,但我什么都没有,所以哪怕是一个螺丝,我都得从零开始手搓。

❌