给定IdA通过两表行集完全匹配查找对应IdB的SQL实现方法
通用SQL实现方案(兼容绝大多数关系型数据库)
核心逻辑通过三层校验保证行集完全一致:
- 校验TableB中IdB对应的总记录数,和指定IdA在TableA中的总记录数相等
- 校验两个表中Code+Value匹配的对数与总记录数相等
- 排除TableB存在多余不匹配记录的情况
对应的SQL代码如下,其中?为你传入的指定IdA参数:
SELECT DISTINCT b.IdB FROM TableB b -- 先获取指定IdA的总记录数 CROSS JOIN ( SELECT COUNT(*) AS a_count FROM TableA WHERE IdA = ? ) a_stat -- 第一层校验:IdB的总记录数和IdA一致 WHERE (SELECT COUNT(*) FROM TableB x WHERE x.IdB = b.IdB) = a_stat.a_count -- 第二层校验:Code+Value完全匹配的对数等于总记录数 AND a_stat.a_count = ( SELECT COUNT(*) FROM TableA a INNER JOIN TableB b2 ON a.Code = b2.Code AND a.Value = b2.Value WHERE a.IdA = ? AND b2.IdB = b.IdB )
简洁版实现(支持EXCEPT/MINUS语法的数据库,如PostgreSQL、SQL Server)
如果你的数据库支持集合差集运算,可以直接通过校验两个行集的差集为空实现,写法更精简:
SELECT b.IdB FROM (SELECT DISTINCT IdB FROM TableB) b WHERE NOT EXISTS ( -- TableA指定IdA的行集减TableB对应IdB的行集,为空代表A的所有行B都包含 SELECT Code, Value FROM TableA WHERE IdA = ? EXCEPT SELECT Code, Value FROM TableB WHERE IdB = b.IdB ) AND NOT EXISTS ( -- TableB对应IdB的行集减TableA指定IdA的行集,为空代表B的所有行A都包含 SELECT Code, Value FROM TableB WHERE IdB = b.IdB EXCEPT SELECT Code, Value FROM TableA WHERE IdA = ? )
效果验证
以你提供的示例数据测试,当传入IdA=123时,两种方案都会返回IdB=X,不会返回多了一条记录的IdB=Z,也不会返回部分匹配的IdB=Y,完全符合匹配规则。
内容的提问来源于stack exchange,提问作者anve
相关产品推荐
相关产品推荐

