Oracle查找不同限制之间的公共位置”;代码“;

Oracle查找不同限制之间的公共位置”;代码“;,oracle,Oracle,这是我的第一个问题。我需要基本上找到一个成分编号的不同限制代码之间的共同位置。限制代码和位置位于它们自己的表中。 我当前的查询返回类似的结果(有更多的数据,但这个问题不需要) 包含所有限制及其位置的表如下所示 restriction_code location ---------------- -------- NN CLE NN LAX NN ORD NN J

这是我的第一个问题。我需要基本上找到一个成分编号的不同限制代码之间的共同位置。限制代码和位置位于它们自己的表中。 我当前的查询返回类似的结果(有更多的数据,但这个问题不需要)

包含所有限制及其位置的表如下所示

restriction_code   location
----------------   --------
NN                 CLE
NN                 LAX
NN                 ORD
NN                 JFK
NN                 PIT
NN                 DFW
R-03               CLE
R-03               LAX
R-02               LAX
R-02               DFW
R-22               JFK
R-03               PIT
ingredient_number  restriction_code common_loc
-----------------  ---------------- ----------
001                NN               LAX
001                R-03             LAX
001                R-02             LAX
002                R-22             JFK
002                NN               JFK
003                R-03             PIT
我需要让结果看起来像这样

restriction_code   location
----------------   --------
NN                 CLE
NN                 LAX
NN                 ORD
NN                 JFK
NN                 PIT
NN                 DFW
R-03               CLE
R-03               LAX
R-02               LAX
R-02               DFW
R-22               JFK
R-03               PIT
ingredient_number  restriction_code common_loc
-----------------  ---------------- ----------
001                NN               LAX
001                R-03             LAX
001                R-02             LAX
002                R-22             JFK
002                NN               JFK
003                R-03             PIT
LAX在所有三个限制代码中都是通用的,因此我们在本例中选择该代码


我猜我将需要使用一个内部连接来连接公共位置,但我不知道如何解决这个问题。任何帮助都将不胜感激!我只需要指向正确的方向。

使用公共表表达式连接两个表。然后根据位置将CTE连接到自身。现在,如果共享的位置超过1个,那么每个成分将获得倍数

WITH CTE AS (T1.Ingredient_Number, T1.Restriction_Code, T2.Location
SELECT *
FROM T1
INNER JOIN T2
 on T1.Restriction_Code = T2.Restriction_Code)

SELECT A.Ingredient_Number, A.Restriction_Code
FROM CTE A
INNE JOIN CTE B
  on A.Ingredient_Number = B.Ingredient_Number
 and A.Location = B.Location

这里有一种方法,可以找到给定成分的所有限制代码所在的所有位置。如果某个成分没有一个位置可以找到所有限制,则该成分将被排除在输出之外。如果一种成分有多个位置可以找到该成分的所有限制代码,则所有这些位置都显示在输出中

在查询的输出中重复某个成分的所有限制代码有点愚蠢;我为满足您条件的每个(配料编号、位置)显示一行

设置:

create table restriction_codes (ingredient_number, restriction_code) as
    select '001', 'NN'   from dual union all
    select '001', 'R-03' from dual union all
    select '001', 'R-02' from dual union all
    select '002', 'R-22' from dual union all
    select '002', 'NN'   from dual union all
    select '003', 'R-03' from dual union all
    select '004', 'CCC'  from dual union all
    select '004', 'DDD'  from dual
;

create table locations (restriction_code, location) as
    select 'NN'  , 'CLE' from dual union all
    select 'NN'  , 'LAX' from dual union all
    select 'NN'  , 'ORD' from dual union all
    select 'NN'  , 'JFK' from dual union all
    select 'NN'  , 'PIT' from dual union all
    select 'NN'  , 'DFW' from dual union all
    select 'R-03', 'CLE' from dual union all
    select 'R-03', 'LAX' from dual union all
    select 'R-02', 'LAX' from dual union all
    select 'R-02', 'DFW' from dual union all
    select 'R-22', 'JFK' from dual union all
    select 'R-03', 'PIT' from dual union all
    select 'CCC' , 'ORD' from dual union all
    select 'DDD' , 'LGA' from dual
;
查询和输出:

with
  prep (ingredient_number, restriction_code, restriction_count) as (
    select ingredient_number, restriction_code, 
           count(*) over (partition by ingredient_number)
    from   restriction_codes
  )
select p.ingredient_number, l.location
from   prep p inner join locations l on p.restriction_code = l.restriction_code
group  by p.ingredient_number, p.restriction_count, l.location
having count(*) = p.restriction_count
order  by p.ingredient_number, l.location
;

INGREDIENT_NUMBER  LOCATION
------------------ --------
001                LAX     
002                JFK     
003                CLE     
003                LAX     
003                PIT 
编辑-OP澄清他确实需要显示输出中的所有输入行(满足要求的(成分、位置)对的每个限制代码对应一行)

以下是如何做到这一点:

select ingredient_number, restriction_code, location
from   (
         select r.ingredient_number, r.restriction_code, l.location,
                count(distinct r.restriction_code) 
                    over (partition by r.ingredient_number) as global_ct,
                count(r.restriction_code) 
                    over (partition by r.ingredient_number, l.location) as local_ct
         from   restriction_codes r inner join locations l 
                                    on r.restriction_code = l.restriction_code
       )
where  global_ct = local_ct
order  by ingredient_number, location, restriction_code
;

INGREDIENT_NUMBER  RESTRICTION_CODE   LOCATION
------------------ ------------------ --------
001                NN                 LAX     
001                R-02               LAX     
001                R-03               LAX     
002                NN                 JFK     
002                R-22               JFK     
003                R-03               CLE     
003                R-03               LAX     
003                R-03               PIT  

实际的表名是什么?您是否尝试过任何可以共享的内容?因为对于给定的配料编号,您必须在同一位置具有所有限制,以这种方式显示输出有什么意义?只需显示一次成分编号就足够了,所有限制代码都位于同一位置。然后:如果有多个公共位置,会发生什么?如果在LAX和LGA都能找到一种成分的所有限制代码,该怎么办?如果一种成分没有共同的位置怎么办?你还应该为该成分显示一些东西吗?例如:对于成分003,单一限制代码为R-03,有三个位置可以找到该限制代码。为什么在输出中只包含其中一个?@mathguy,请不要太详细,但这些位置基本上是我的钢铁供应商的替身。它必须显示每个成分的编号的原因是,在我已经编写的查询的一部分中,它分解了每个限制代码的需求(以磅为单位)。我还将有一个基于限制代码的每个位置的权重表,它将解决一个限制代码有三个位置的问题。另外,如果没有公共位置,它可以是空的。好的,我会编辑我的答案,告诉你如何得到你需要的。除了明显的语法错误:
使用cte as(选择某物或其他)
,我想知道如何找到一种成分的所有限制代码所在的位置。一种成分可能有五个限制——你必须找到一个能找到所有五个限制的位置。您的代码将如何做到这一点?非常感谢您,这个解决方案对我很有效。我只是忘了给你一个公认的答案!