如何在SQL中反复应用过滤条件直至查询结果稳定?
迭代过滤直到结果稳定的解决方案
你需要的是收敛式迭代过滤:反复应用属性重复规则,直到最终行集合不再变化,且集合内每一行同时满足:同一ID下,其Property A值至少出现2次、Property B值也至少出现2次。可以用**递归CTE(公共表表达式)**实现该逻辑,以下是具体方案:
实现示例(以PostgreSQL为例)
WITH RECURSIVE filtered AS ( -- 初始步骤:先取符合Property B重复规则的行(与你的示例初始逻辑对齐,也可直接用全表作为起始) SELECT * FROM your_table WHERE EXISTS ( SELECT 1 FROM your_table t2 WHERE t2.ID = your_table.ID AND t2."Property B" = your_table."Property B" GROUP BY t2.ID, t2."Property B" HAVING COUNT(*) >= 2 ) UNION ALL -- 递归步骤:基于上一轮结果,过滤出同时满足两个属性规则的行 SELECT t.* FROM filtered t WHERE -- 同一ID下,当前行的Property A在本轮集合中至少出现2次 EXISTS ( SELECT 1 FROM filtered t2 WHERE t2.ID = t.ID AND t2."Property A" = t."Property A" GROUP BY t2.ID, t2."Property A" HAVING COUNT(*) >= 2 ) AND -- 同一ID下,当前行的Property B在本轮集合中至少出现2次 EXISTS ( SELECT 1 FROM filtered t2 WHERE t2.ID = t.ID AND t2."Property B" = t."Property B" GROUP BY t2.ID, t2."Property B" HAVING COUNT(*) >= 2 ) -- 排除已符合条件的行,避免无限递归 EXCEPT SELECT * FROM filtered ) -- 取最终收敛结果:去重后得到稳定的行集合 SELECT DISTINCT ID, "Property A", "Property B" FROM filtered;
逻辑说明
- 初始CTE:先筛选出符合Property B重复规则的行,与你示例的第一步逻辑一致;若需要从全表开始迭代,直接替换成
SELECT * FROM your_table即可。 - 递归迭代:每一轮都基于上一轮的结果,只保留同时满足两个属性重复规则的行,通过
EXCEPT避免重复处理已达标的行,直到没有新行被过滤。 - 最终结果:当递归不再产生新的过滤结果时,去重后得到稳定的最终集合。
针对你的示例数据,最终结果会是:
| ID | Property A | Property B |
|---|---|---|
| 2 | UVW | GHI |
| 2 | UVW | GHI |
这两行同时满足:ID=2下,Property A=UVW出现2次,Property B=GHI出现2次,且后续迭代不会再产生变化。
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

