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
我使用代表大型机数据的 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