查询以检查记录的一致性

时间:2010-06-17 23:32:30

标签: sql plsql

我有四张桌子

表A:

  • ID1
  • ID2
  • ID3

表B:

  • ID1
  • 递减

表C:

  • ID2
  • 递减

提出:

  • ID3
  • 递减

我需要做的是检查表A中是否存在表B C和D中id1 id2 id3的所有组合。换句话说,表A应该包含id1 id2和id3的所有可能组合,这些组合存储在其他三个表中。

1 个答案:

答案 0 :(得分:2)

此查询评估id1,id2和id3(交叉连接)的所有组合,并查找表a中不存在的组合。

select b.id1, c.id2, d.id3 from
 TableB b cross join TableC c cross join TableD d WHERE NOT EXIST
 (select 1 FROM TableA a WHERE a.id1=b.id1 AND a.id2=c.id2 AND a.id3=d.id3)

编辑:有正确的加入

SELECT allPerms.id1, allPerms.id2, allPerms.id3 FROM a RIGHT JOIN (select b.id1, c.id2, d.id3 from
 TableB b cross join TableC c cross join TableD) allPerms
 ON a.id1=allPerms.id1 AND a.id2=allPerms.id2 AND a.id3=allPerms.id3
 WHERE a.id1 IS NULL

两者几乎相同。由于我们实际上并未从连接表中获取值,因此有些人更喜欢第一种方法,因为它捕获了查询的意图和精神。第二个版本更“面向实现”。一个好的优化器将为两者产生一个有效的计划,但在一些较小的RDBMS上,第二个版本将运行得更快。

使用表D的预定义集 - id3具有值(2,5,6)

select b.id1, c.id2 from
 TableB b cross join TableC c WHERE NOT EXIST
 (select 1 FROM TableA a WHERE a.id1=b.id1 AND a.id2=c.id2 AND a.id3 IN (2,5,6))

但是,这并没有给你表A行中缺少的id3。为此,我认为最简单的方法是通过联合来模拟表格,例如

select b.id1, c.id2, d.id3 from
 TableB b, TableC c, (select 2 id3 union select 5 union select 6) d 
WHERE NOT EXIST
 (select 1 FROM TableA a WHERE a.id1=b.id1 AND a.id2=c.id2 AND a.id3=d.id3)

(这仍然使用交叉连接 - 如果用逗号分隔表,则暗示它。)