我有一张带>的桌子1'000'000个条目;此表从大约130个其他表中引用。我的问题是很多这些1-mio条目都是旧的和未使用的。
找到未被任何其他表引用的条目的紧固方法是什么?我不喜欢做
select * from (
select * from table-a TA
minus
select * from table-a TA where TA.id in (
select "ID" from (
(select distinct FK-ID "ID" from table-b)
union all
(select distinct FK-ID "ID" from table-c)
...
是否有更简单,更通用的方式?
谢谢大家!
答案 0 :(得分:7)
你可以这样做:
select * from table_a a
where not exists (select * from table_b where fk_id = a.id)
and not exists (select * from table_c where fk_id = a.id)
and not exists (select * from table_d where fk_id = a.id)
...
答案 1 :(得分:0)
尝试:
select a.*
from table_a a
left join table_b b on a.id=b.fk_id
left join table_c c on a.id=c.fk_id
left join table_d d on a.id=d.fk_id
left join table_e e on a.id=e.fk_id
......
where b.fk_id is null
and c.fk_id is null
and d.fk_id is null
and e.fk_id is null
.....
您也可以尝试:
select a.*
from table_a a
left join
(select b.fk_id from table_b b union
select c.fk_id from table_c c union
...) table_union on a.id=table_union.fk_id
where table_union.fk_id is null
这更像是面向SQL,它不会像上面的解决方案那样永远。
答案 2 :(得分:0)
不确定效率,但是:
select * from table_a
where id not in (
select id from table_b
union
select id from table_c )
如果您关注的是允许数据库继续正常操作,而您可以将其分成多个阶段:
insert into tblIds
select id from table_a
union
select id from table_b
根据您的需要,然后:
delete * from table_a where id not in ( select id from tableIds )
当然,有时候进行大量处理需要花费很多时间。
答案 3 :(得分:0)
我喜欢上面@ Patrick的回答,但我想补充一点 您可以通过扫描sysObjects,查找关键关系并生成INSERT语句来构建这些INSERT语句,而不是手动构建130步查询。
这不仅可以节省您的时间,还可以帮助您确定您是否覆盖了所有表格 - 可能有131个,或者只有129个。
答案 4 :(得分:0)
我倾向于Marcelo Cantos的回答(并且已经赞成它),但是这里有一个替代方案,试图避免在外键上没有索引的问题......
WITH
ids_a AS
(
SELECT id FROM myTable
)
,
ids_b AS
(
SELECT id FROM ids_a WHERE NOT EXISTS (SELECT * FROM table_a WHERE fk_id = ids_a.id)
)
,
ids_c AS
(
SELECT id FROM ids_b WHERE NOT EXISTS (SELECT * FROM table_b WHERE fk_id = ids_b.id)
)
,
...
,
ids_z AS
(
SELECT id FROM ids_y WHERE NOT EXISTS (SELECT * FROM table_y WHERE fk_id = ids_y.id)
)
SELECT * FROM ids_z
我所要做的就是向甲骨文建议订购,以尽量减少其努力。不幸的是,Oracle会将其编译为非常类似于Marcelo Cantos的答案,并且它可能不会有任何不同的表现。