Oracle在不同限制“代码”之间找到共同的位置

问题描述 投票:1回答:2

这是我的第一个问题。我需要从根本上找到不同限制代码之间的共同位置,以找到一个配料号。这些限制代码和位置位于各自的表中。我当前的查询返回了类似的内容(对此有更多数据,但此问题不需要)

ingredient_number   restriction_code
-----------------   -------------------
 001                NN
 001                R-03
 001                R-02
 002                R-22
 002                NN
 003                R-03

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

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对于所有三个限制代码都是通用的,因此在此示例中选择一个。

我猜测我将需要使用内部联接来联接公共位置,但是我对如何弄清楚这一点不知所措。任何帮助将不胜感激!我只需要指出正确的方向。

oracle
2个回答
0
投票

这里是一种方法,查找可以找到给定成分的所有限制代码的所有位置。如果对于某个成分没有一个可以找到所有限制的位置,那么将从输出中将该成分排除。如果某个成分存在多个位置,可以找到该成分的所有限制代码,则所有这些位置都会显示在输出中。

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

设置:

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 

EDIT-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  

-1
投票

使用公共表表达式将两个表连接在一起。然后根据位置将CTE加入自身。现在,如果共享一个以上的位置,则每种成分将获得多个。

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
© www.soinside.com 2019 - 2024. All rights reserved.