Oracle join 使用两个可能的列数据

Oracle join using two possible column data

我使用代表大型机数据的 Oracle 12 数据库。这是我的问题。

我们有两层层次结构,"System" 和 "Prin"。将它们想象成美国的州和县。有时,客户端会在系统级别构建所有内容,并且它的所有子项都将始终引用系统配置。在 Prin 级别构建的其他客户端,以及 prin 的子级首先必须查看 PRIN 级别的数据以进行配置,如果 prin 未构建在 table 中,则默认为系统级配置。很简单。

这里是我无法让 table 加入工作的地方。单个客户端可以在系统级别构建一些系统,而在原则级别构建其他系统。当我不确定客户端在该特定原则中使用的配置时,如何动态加入?

示例:

WITH tbl as (
select 80 SYSTEM, 0 PRIN, 2 DATA from dual
union
select 80 , 1 , 3  from dual
union
select 80 , 2 , 4 from dual
)

现在,如果我有一个位于系统 80 prin 3 中的项目...它将需要 0 prin 数据,因为 0 表示 "system" 配置。

所以如果我有原则 1,我想要数据“3”。如果我有 prin 2,数据“4”,如果我有 prin 8,我想要数据“2”,因为没有构建 prin 8 配置。

看到我要去的地方了吗?

所以当我这样做时

select *
from tbl t
inner join tbl2 tt on t.sys = tt.sys and prin =  ?????

怎么说"if prin is built in tbl, use prin, otherwise default to prin = 0"

我知道这是一个表述不当的问题。所以请询问更多细节,我会尽快回答。这影响了多个 table。

非常丑陋,但数据模型也是如此...

with
     tbl ( s, prim, val ) as (
       select 80, 0, 2 from dual union all
       select 80, 1, 3 from dual union all
       select 80, 2, 4 from dual
     ),
     inputs ( s, prim ) as (
       select 80, 1 from dual union all
       select 80, 5 from dual
     )
select t.s, i.prim i_prim, t.prim tbl_prim, t.val
from   tbl t join inputs i
             on t.s = i.s
             and
             (    t.prim = i.prim 
               or t.prim = 0 
               and not exists ( select * from tbl 
                                where s = i.s and prim = i.prim ))
;

   S     I_PRIM   TBL_PRIM        VAL
---- ---------- ---------- ----------
  80          5          0          2
  80          1          1          3

2 rows selected.

我不建议您在稍大的表 (50k+) 上使用带有 OR 条件的(复杂的)JOIN,因为根据我自己的经验,执行计划可能会完全出错。

在这种情况下宁愿使用 Union (select cond1_match) union all (select cond2_default) ordered/ranked 和 select 第一行或使用 JOIN like

select coalesce(a1.prin, a2.prin) 
from (select cond1_match) a1 
full join (select cond2_default) a2

如果你的理解是正确的,你只有一个数字作为输入并想加入另一个数据表,那么我的建议是这样的

with
     tbl ( SYSTEM, PRIN, DATA ) as (
       select 80, 0, 2 from dual union all
       select 80, 1, 3 from dual union all
       select 80, 2, 4 from dual
     ),
     tbl2 (SYSTEM, PRIN, OTHERDATA) as (
       select 80, 0, 99 from dual union all
       select 80, 1, 333 from dual union all
       select 80, 2, 444 from dual
     )
select t.system, t.prin, t.data, tt.otherdata
from tbl t
inner join tbl2 tt on t.system = tt.system and t.prin = tt.prin 
where t.prin = (select nvl(max(prin), 0) from tbl where system = t.system and prin = :pri)
;

system + prin 必须是唯一的,否则 max() 将是随机的

:pri = 5

SYSTEM  PRIN    DATA    OTHERDATA
------  ----    ----    ---------
80      0       2       99

:pri = 2

SYSTEM  PRIN    DATA    OTHERDATA
------  ----    ----    ---------
80      2       4       444

只是猜测 tbl2 和连接条件,但这基本上就是我被告知如何查找数据或使用默认值 if no_data_found in SQL