Omr*_*mri 3 sql oracle join intersection
我正在使用Oracle SQL,我有一个关于join命令的基本问题.
我有5张桌子.它们中的每一个都与主键具有相同的列:ID (int).让我们看看以下查询:
select count(*) from table_a - 100 records
select count(*) from table_c - 200 records
select count(*) from table_c - 150 records
select count(*) from table_d - 100 records
select count(*) from table_e - 120 records
Run Code Online (Sandbox Code Playgroud)
select * -- 88 records
from table_a a
inner join table b
on a.id = b.id
inner join table c
on a.id = c.id
inner join table d
on a.id = d.id
inner join table e
on a.id = e.id
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果其中一个表不包含某个ID(即使其中包含其余的ID),许多记录也无法包含在输出中.我怎么知道这些"坏"记录是什么?它实际上是我认为的交叉点的补充.
我想知道每个案例的问题记录和表格是什么.例如:ID 123是一个"坏"记录,因为它不包含在table_c中,但包含在其余表中.ID 321是一个有问题的记录,因为它包含在除table_d之外的所有表中.
您可能正在寻找所有表之间的对称差异.
要解决这类问题而不太聪明,你需要FULL OUTER JOIN ... USING:
SELECT id
FROM table_a
FULL OUTER JOIN table_b USING(id)
FULL OUTER JOIN table_c USING(id)
FULL OUTER JOIN table_d USING(id)
FULL OUTER JOIN table_e USING(id)
WHERE table_a.ROWID IS NULL
OR table_b.ROWID IS NULL
OR table_c.ROWID IS NULL
OR table_d.ROWID IS NULL
OR table_e.ROWID IS NULL;
Run Code Online (Sandbox Code Playgroud)
该FULL OUTER JOIN会返回满足连接条件(像一个普通的所有行JOIN),以及所有的行没有相应的行.该USING条款嵌入COALESCE了equijoin专栏.
另一种选择是使用反连接:
SELECT id
FROM table_a
FULL OUTER JOIN table_b USING(id)
FULL OUTER JOIN table_c USING(id)
FULL OUTER JOIN table_d USING(id)
FULL OUTER JOIN table_e USING(id)
WHERE id NOT IN (
SELECT id
FROM table_a
INNER JOIN table_b USING(id)
INNER JOIN table_c USING(id)
INNER JOIN table_d USING(id)
INNER JOIN table_e USING(id)
)
Run Code Online (Sandbox Code Playgroud)
基本上,这将构建联合所有集合减去所有集合的交集.
在图形上,您可以比较INNER JOIN 和OUTER JOIN(在3个表上仅为了便于表示):


考虑到测试用例:
Run Code Online (Sandbox Code Playgroud)ID TABLE_A TABLE_B TABLE_C TABLE_D TABLE_E 1 * - - - - 2 - * * * * 3 * - - * - 4 * * * * *
*-缺少条目的表中的值
两个查询都将产生:
ID
1
3
2
Run Code Online (Sandbox Code Playgroud)
如果需要表格结果,可以通过添加一组CASE表达式来调整其中一个查询.像这样的东西:
SELECT ID,
CASE when table_a.rowid is not null then 1 else 0 END table_a,
CASE when table_b.rowid is not null then 1 else 0 END table_b,
CASE when table_c.rowid is not null then 1 else 0 END table_c,
CASE when table_d.rowid is not null then 1 else 0 END table_d,
CASE when table_e.rowid is not null then 1 else 0 END table_e
FROM table_a
FULL OUTER JOIN table_b USING(id)
FULL OUTER JOIN table_c USING(id)
FULL OUTER JOIN table_d USING(id)
FULL OUTER JOIN table_e USING(id)
WHERE table_a.ROWID IS NULL
OR table_b.ROWID IS NULL
OR table_c.ROWID IS NULL
OR table_d.ROWID IS NULL
OR table_e.ROWID IS NULL;
Run Code Online (Sandbox Code Playgroud)
生产:
Run Code Online (Sandbox Code Playgroud)ID TABLE_A TABLE_B TABLE_C TABLE_D TABLE_E 1 1 0 0 0 0 3 1 0 0 1 0 2 0 1 1 1 1
10缺少条目的表中的值