【发布时间】:2010-06-17 23:32:30
【问题描述】:
我有四张桌子
表A:
- id1
- id2
- id3
- 价值
表B:
- id1
- 描述
表C:
- id2
- 描述
表D:
- id3
- 描述
我需要做的是检查表 B C 和 D 中 id1 id2 id3 的所有组合是否存在于表 A 中。换句话说,表 A 应该包含存储在其他三个表中的 id1 id2 和 id3 的所有可能组合。
【问题讨论】:
我有四张桌子
我需要做的是检查表 B C 和 D 中 id1 id2 id3 的所有组合是否存在于表 A 中。换句话说,表 A 应该包含存储在其他三个表中的 id1 id2 和 id3 的所有可能组合。
【问题讨论】:
此查询评估 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)
(这仍然使用交叉连接 - 如果表用逗号分隔,则暗示它。)
【讨论】: