Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 验证表中所有组合是否存在_Sql_Database_Oracle_Combinations - Fatal编程技术网

Sql 验证表中所有组合是否存在

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

我想为oracle编写一个查询,以验证表中是否存在所有组合。 我的问题是,表的“键列”是链接到其他表的FK,这意味着这些组合基于其他表的行

ERD示例:
因此,如果表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时短路。如果需要一个列表,那么最好的方法可能取决于可用的索引。在小型数据集上,性能似乎不是什么大问题,但从性能角度习惯最佳实践是一个好习惯,可以在一天中养成