如何筛选表A中任意parent列匹配表B user_id列值的记录
筛选表A匹配表B user_id记录的实现方案
方案1:全兼容通用写法
适配所有关系型数据库,逻辑最直观:
SELECT DISTINCT A.* FROM 表A A WHERE A.parent1 IN (SELECT user_id FROM 表B) OR A.parent2 IN (SELECT user_id FROM 表B) OR A.parent3 IN (SELECT user_id FROM 表B) OR A.parent4 IN (SELECT user_id FROM 表B) OR A.parent5 IN (SELECT user_id FROM 表B) OR A.parent6 IN (SELECT user_id FROM 表B) OR A.parent7 IN (SELECT user_id FROM 表B);
说明:加DISTINCT是为了避免表B存在重复user_id时返回重复的A表记录,若表B的user_id是唯一主键可去掉该关键字
方案2:高性能EXISTS写法
推荐日常使用,尤其表B数据量较大时性能远优于方案1:
SELECT A.* FROM 表A A WHERE EXISTS ( SELECT 1 FROM 表B B WHERE B.user_id IN (A.parent1, A.parent2, A.parent3, A.parent4, A.parent5, A.parent6, A.parent7) );
说明:该写法仅需扫描一次表B,匹配到符合条件的记录就会终止校验,无需额外去重
方案3:高可扩展UNPIVOT写法
适配支持UNPIVOT语法的数据库(Oracle、SQL Server、PostgreSQL 12+等),后续新增parent代次时修改成本更低:
SELECT DISTINCT A.* FROM 表A A UNPIVOT ( parent_id FOR parent_level IN (parent1, parent2, parent3, parent4, parent5, parent6, parent7) ) UP INNER JOIN 表B B ON UP.parent_id = B.user_id;
优化建议
- 给表B的user_id列添加索引,可大幅提升所有方案的查询效率
- 若表A的parent列存在空值无需额外处理,NULL不会和表B的有效user_id匹配
内容的提问来源于stack exchange,提问作者user1543784
相关产品推荐
相关产品推荐

