Sql 验证表中所有组合是否存在
我想为oracle编写一个查询,以验证表中是否存在所有组合。 我的问题是,表的“键列”是链接到其他表的FK,这意味着这些组合基于其他表的行 ERD示例:Sql 验证表中所有组合是否存在,sql,database,oracle,combinations,Sql,Database,Oracle,Combinations,我想为oracle编写一个查询,以验证表中是否存在所有组合。 我的问题是,表的“键列”是链接到其他表的FK,这意味着这些组合基于其他表的行 ERD示例: 因此,如果表A中有3行(1-3),表B中有4行,表C中有2行,MyTable必须有这些行(3x4x2,总共24行): 我不知道该怎么写,因为组合的可用数据可能会改变 谢谢你的帮助 所以,MyTable中的总行数应该等于其他表中总行数的乘积,您可以这样尝试: select case when (select count(*) from MyTab
因此,如果表A中有3行(1-3),表B中有4行,表C中有2行,MyTable必须有这些行(3x4x2,总共24行): 我不知道该怎么写,因为组合的可用数据可能会改变
谢谢你的帮助 所以,MyTable中的总行数应该等于其他表中总行数的乘积,您可以这样尝试:
select
case when (select count(*) from MyTable) =
((select count(*) from TableA) * (select count(*) from TableB)... )
then 'Everything is fine'
else 'Some rows are missing' end
from dual
仅当对(fk_a、fk_b、fc_…)具有唯一约束时,此选项才有效
如果没有,可以使用distinct
select
case when (select count(distinct concat(fk_a, fk_b,....)) from MyTable) =
((select count(*) from TableA) * (select count(*) from TableB)... )
then 'Everything is fine'
else 'Some rows are missing' end
from dual
所以,MyTable中的总行数应该等于其他表中总行数的乘积,您可以这样尝试:
select
case when (select count(*) from MyTable) =
((select count(*) from TableA) * (select count(*) from TableB)... )
then 'Everything is fine'
else 'Some rows are missing' end
from dual
仅当对(fk_a、fk_b、fc_…)具有唯一约束时,此选项才有效
如果没有,可以使用distinct
select
case when (select count(distinct concat(fk_a, fk_b,....)) from MyTable) =
((select count(*) from TableA) * (select count(*) from TableB)... )
then 'Everything is fine'
else 'Some rows are missing' end
from dual
为了获得可能的组合,交叉连接起作用 因此,您可以使用以下工具获得24行:
with a as (
select 1 id1 from dual union all
select 2 id1 from dual union all
select 3 id1 from dual )
, b as (
select 1 id2 from dual union all
select 2 id2 from dual union all
select 3 id2 from dual union all
select 4 id2 from dual )
, c as (
select 1 id3 from dual union all
select 2 id3 from dual )
select id1, id2, id3
from a cross join b cross join c;
从这里开始,查找表中存在或不存在的组合是一个相当简单的步骤。要获取不在目标表中的组合,可以:
with a as (
select 1 id1 from dual union all
select 2 id1 from dual union all
select 3 id1 from dual )
, b as (
select 1 id2 from dual union all
select 2 id2 from dual union all
select 3 id2 from dual union all
select 4 id2 from dual )
, c as (
select 1 id3 from dual union all
select 2 id3 from dual )
, t as (
select 1 id1, 1 id2, 1 id3 from dual union all
select 1 id1, 1 id2, 2 id3 from dual union all
select 1 id1, 2 id2, 1 id3 from dual union all
select 1 id1, 2 id2, 2 id3 from dual union all
select 1 id1, 3 id2, 1 id3 from dual union all
select 1 id1, 4 id2, 2 id3 from dual )
select lst.id1, lst.id2, lst.id3
from (
select id1, id2, id3
from a cross join b cross join c ) lst
where not exists (select 1 from t
where t.id1 = lst.id1
and t.id2 = lst.id2
and t.id3 = lst.id3)
或者,使用不在测试中的:
select lst.id1, lst.id2, lst.id3
from (
select id1, id2, id3
from a cross join b cross join c ) lst
where (id1, id2, id3) not IN (select distinct id1, id2, id3 from t)
Alex的减号做了同样的事情,所有的结果都是相同的——哪个选项最有效可能取决于复合表中记录的数量、可用索引,以及——最重要的——您想要的确切内容
如果您只是想知道有一个或多个缺少的组合,那么请使用一个尽可能快地短路的选项。例如,EXISTS将在遇到计算结果为TRUE的案例时停止检查,以获得可能的组合,交叉连接起作用 因此,您可以使用以下工具获得24行:
with a as (
select 1 id1 from dual union all
select 2 id1 from dual union all
select 3 id1 from dual )
, b as (
select 1 id2 from dual union all
select 2 id2 from dual union all
select 3 id2 from dual union all
select 4 id2 from dual )
, c as (
select 1 id3 from dual union all
select 2 id3 from dual )
select id1, id2, id3
from a cross join b cross join c;
从这里开始,查找表中存在或不存在的组合是一个相当简单的步骤。要获取不在目标表中的组合,可以:
with a as (
select 1 id1 from dual union all
select 2 id1 from dual union all
select 3 id1 from dual )
, b as (
select 1 id2 from dual union all
select 2 id2 from dual union all
select 3 id2 from dual union all
select 4 id2 from dual )
, c as (
select 1 id3 from dual union all
select 2 id3 from dual )
, t as (
select 1 id1, 1 id2, 1 id3 from dual union all
select 1 id1, 1 id2, 2 id3 from dual union all
select 1 id1, 2 id2, 1 id3 from dual union all
select 1 id1, 2 id2, 2 id3 from dual union all
select 1 id1, 3 id2, 1 id3 from dual union all
select 1 id1, 4 id2, 2 id3 from dual )
select lst.id1, lst.id2, lst.id3
from (
select id1, id2, id3
from a cross join b cross join c ) lst
where not exists (select 1 from t
where t.id1 = lst.id1
and t.id2 = lst.id2
and t.id3 = lst.id3)
或者,使用不在测试中的:
select lst.id1, lst.id2, lst.id3
from (
select id1, id2, id3
from a cross join b cross join c ) lst
where (id1, id2, id3) not IN (select distinct id1, id2, id3 from t)
Alex的减号做了同样的事情,所有的结果都是相同的——哪个选项最有效可能取决于复合表中记录的数量、可用索引,以及——最重要的——您想要的确切内容
如果您只是想知道有一个或多个缺少的组合,那么请使用一个尽可能快地短路的选项。例如,EXISTS将在遇到计算结果为TRUE的情况时停止检查您可以识别所有可能的组合,这些组合将生成行的笛卡尔积:
select a.id, b.id, c.id
from tablea a
cross join tableb b
cross join tablec c
根据您想要的确切结果,您可以以各种方式使用它来查看您拥有或没有什么。要列出不存在的组合,请使用:
或者您可以使用不存在
代替减号,如其他答案所示
如果要将它们与主表的列(如果存在)一起列出,否则为null,则可以使用左外部联接:
select a.id, b.id, c.id, mt.id
from tablea a
cross join tableb b
cross join tablec c
left join my_table mt
on mt.fk_a = a.id and mt.fk_b = b.id and mt.fk_c = c.id
您还可以计算第一次查询的结果,然后在
case
语句中使用该结果,以获得简单的yes/no答案,以显示是否存在所有组合。依此类推-这实际上取决于您希望看到的内容。您可以识别所有可能的组合,这些组合生成行的笛卡尔积:
select a.id, b.id, c.id
from tablea a
cross join tableb b
cross join tablec c
根据您想要的确切结果,您可以以各种方式使用它来查看您拥有或没有什么。要列出不存在的组合,请使用:
或者您可以使用不存在
代替减号,如其他答案所示
如果要将它们与主表的列(如果存在)一起列出,否则为null,则可以使用左外部联接:
select a.id, b.id, c.id, mt.id
from tablea a
cross join tableb b
cross join tablec c
left join my_table mt
on mt.fk_a = a.id and mt.fk_b = b.id and mt.fk_c = c.id
您还可以计算第一次查询的结果,然后在
case
语句中使用该结果,以获得简单的yes/no答案,以显示是否存在所有组合。依此类推-这实际上取决于您希望看到什么。使用交叉连接
从三个(或更多)表中获取记录集的笛卡尔积,并应用不存在
子句,为您提供mytable
中不存在的行(在输出中)
select a.id, b.id, c.id
from tbla a cross join tblb b cross join tblc c
where not exists (
select 1
from mytable t
where t.fk_a = a.id
and t.fk_b = b.id
and t.fk_c = c.id
)
使用
CROSS-JOIN
从三个(或更多)表中获取记录集的笛卡尔积,并应用NOT EXISTS
子句,为您提供mytable
中不存在的行(在输出中)
select a.id, b.id, c.id
from tbla a cross join tblb b cross join tblc c
where not exists (
select 1
from mytable t
where t.fk_a = a.id
and t.fk_b = b.id
and t.fk_c = c.id
)
您是否试图查询您拥有的所有组合,或识别任何缺失的组合,或获取一个简单的是/否标志来说明是否缺失任何组合?识别缺失的组合/获取一个是/否标志。这两个选项都很好。从性能的角度来看,这个选项很重要。如果您只需要一个yes/no标志,那么带有EXISTS或NOT IN的查询将在第一个TRUE时短路。如果需要一个列表,那么最好的方法可能取决于可用的索引。在小型数据集上,性能似乎不是什么大问题,但当现实世界向您抛出数百万(或数亿)行时,从性能角度习惯最佳实践是一个好习惯。您是否尝试查询所有现有的组合,或者识别任何缺失的组合,或者获取一个简单的是/否标志来说明是否有缺失?识别缺失的组合/获取一个是/否标志。这两个选项都很好。从性能的角度来看,这个选项很重要。如果您只需要一个yes/no标志,那么带有EXISTS或NOT IN的查询将在第一个TRUE时短路。如果需要一个列表,那么最好的方法可能取决于可用的索引。在小型数据集上,性能似乎不是什么大问题,但从性能角度习惯最佳实践是一个好习惯,可以在一天中养成