所以我的数据库中有两个名为VAL和VAL_SUB的表。在这种情况下,主键/驱动程序表是一个称为MAIN的表(如下所示)
MAIN_ID MAIN_NAME CREATED_DT Units
1 Height DEC-14-18 INches
2 Weight DEC-12-18 LBs
我目前有一个过程/作业,可以计算值来替代VAL表中的“极端”,空值或缺失值。 VAL表将包含在其中解析的所有原始数据(如下所示):
VAL_ID VAL Hour Date
1 -87 01:00 AM NOV-30-18
2 8 02:00 AM NOV-30-18
3 18 03:00 AM NOV-30-18
VAL_SUB将包含使用上述逻辑更新/替换的所有值,以及“未触及”的值。
VAL_SUB_ID VAL Hour Date
1 12 01:00 AM NOV-30-18
VAL和VAL_SUB表将分别具有一个与MAIN表的关系表(如下所示)
VAL_MAIN_REL
VAL_MAIN_ID VAL_ID MAIN_ID
1 1 2
2 2 2
3 3 1
VAL_SUB_MAIN_REL
VAL_SUB_MAIN_ID VAL_SUB_ID MAIN_ID
1 1 2
我需要一个查询,以在一个表/行中显示“ subbed”和原始值(如下所示):
MAIN_ID ORIG_VAL SUB_VAL UNITS HOUR DATE
1 18 null Inches 03:00 AM 30-NOV-18
2 8 null LBS 02:00 AM 30-NOV-18
2 -87 12 LBS 01:00 AM 30-NOV-18
我尝试了以下操作,但未产生所需的输出(相反,它为orig val和sub val列均返回null)是否需要进行某种分组?:
select m.main_id
, v.val as ORIG_VAL
, sv.val as SUB_VAL
, m.units
, v.hour
, v.date
from main m
join VAL_MAIN_REL VMR on m.main_id = vmr.main_id
join VAL V on VMR.val_id = V.val_id
join VAL_SUB_MAIN_REL VSMR on vsmr.main_id = m.main_id
join VAL_SUB VS on VSMR.VAL_ID = vs.VAL_SUB_ID;
答案 0 :(得分:1)
使用左联接一次联接一个表
SELECT m.main_id, v.val as ORIG_VAL, sv.val as SUB_VAL, m.units, v.hour, v.date
FROM main m
LEFT JOIN VAL_MAIN_REL vm ON vm.main_id = m.main_id
JOIN val v ON vm.val_id = v.val_id
LEFT JOIN val_sub_main_rel sm ON sm.main_id = m.main_id
JOIN val_sub sv ON sm.val_sub_id = sv.val_sub_id
WHERE v.hour = sv.hour
AND v.date = sv.date
答案 1 :(得分:1)
您似乎想要左外部联接,该联接基于两个表中的“ sub”关系和匹配的日期/时间:
select m.main_id,
v.val as orig_val,
vs.val as sub_val,
m.units,
v.hour,
v.date
from main m
join val_main_rel vmr on vmr.main_id = m.main_id
join val v on v.val_id = vmr.val_id
left join val_sub_main_rel vsmr on vsmr.main_id = m.main_id
left join val_sub vs on vs.val_sub_id = vsmr.val_sub_id
and vs.date_ = v.date
and vs.hour = v.hour;
使用CTE进行示例数据的快速演示,“日期”列重命名为“ date_”,因此它是有效的标识符:
-- CTEs for sample data, with 'date_' instead of 'date'
with main (main_id, main_name, created_dt, units) as (
select 1, 'Height', date '2018-12-14', 'INches' from dual
union all select 2, 'Weight', date '2018-12-12', 'LBs' from dual
),
val (val_id, val, hour, date_) as (
select 1, -87, '01:00 AM', date '2018-11-30' from dual
union all select 2, 8, '02:00 AM', date '2018-11-30' from dual
union all select 3, 18, '03:00 AM', date '2018-11-30' from dual
),
val_sub (val_sub_id, val, hour, date_) as (
select 1, 12, '01:00 AM', date '2018-11-30' from dual
),
val_main_rel (val_main_id, val_id, main_id) as (
select 1, 1, 2 from dual
union all select 2, 2, 2 from dual
union all select 3, 3, 1 from dual
),
val_sub_main_rel (val_sub_main_id, val_sub_id, main_id) as (
select 1, 1, 2 from dual
)
-- actual query
select m.main_id,
v.val as orig_val,
vs.val as sub_val,
m.units,
v.hour,
v.date_
from main m
join val_main_rel vmr on vmr.main_id = m.main_id
join val v on v.val_id = vmr.val_id
left join val_sub_main_rel vsmr on vsmr.main_id = m.main_id
left join val_sub vs on vs.val_sub_id = vsmr.val_sub_id
and vs.date_ = v.date_
and vs.hour = v.hour;
MAIN_ID ORIG_VAL SUB_VAL UNITS HOUR DATE_
---------- ---------- ---------- ------ -------- ----------
2 -87 12 LBs 01:00 AM 2018-11-30
2 8 LBs 02:00 AM 2018-11-30
1 18 INches 03:00 AM 2018-11-30
您在实际main_id
表中拥有的多个外部联接和重复的val_sub
条目正在密谋进行不必要的匹配,如您在注释中所述。 vsmr
关系表存在一个匹配项,但是考虑到日期/小时之后,该表并没有vs
表中的匹配项-但是第一个外部联接匹配项足以在表中产生多余的行。输出。
修改后的CTE具有第二个子值:
-- CTEs for sample data, with 'date_' instead of 'date'
with main (main_id, main_name, created_dt, units) as (
select 1, 'Height', date '2018-12-14', 'INches' from dual
union all select 2, 'Weight', date '2018-12-12', 'LBs' from dual
),
val (val_id, val, hour, date_) as (
select 1, -87, '01:00 AM', date '2018-11-30' from dual
union all select 2, 8, '02:00 AM', date '2018-11-30' from dual
union all select 3, 18, '03:00 AM', date '2018-11-30' from dual
),
val_sub (val_sub_id, val, hour, date_) as (
select 1, 12, '01:00 AM', date '2018-11-30' from dual
-- extra row added below
union all select 2, 13, '02:00 AM', date '2018-11-30' from dual
),
val_main_rel (val_main_id, val_id, main_id) as (
select 1, 1, 2 from dual
union all select 2, 2, 2 from dual
union all select 3, 3, 1 from dual
),
val_sub_main_rel (val_sub_main_id, val_sub_id, main_id) as (
select 1, 1, 2 from dual
-- extra row added below
union all select 2, 2, 2 from dual
)
...
原始查询得到:
MAIN_ID ORIG_VAL SUB_VAL UNITS HOUR DATE_
---------- ---------- ---------- ------ -------- ----------
2 -87 12 LBs 01:00 AM 2018-11-30
2 8 13 LBs 02:00 AM 2018-11-30
2 8 LBs 02:00 AM 2018-11-30
1 18 INches 03:00 AM 2018-11-30
2 -87 LBs 01:00 AM 2018-11-30
因此,我认为您需要通过子查询消除这些错误,因此您可以执行单个外部联接:
select m.main_id,
v.val as orig_val,
vsx.val as sub_val,
m.units,
v.hour,
v.date_
from main m
join val_main_rel vmr on vmr.main_id = m.main_id
join val v on v.val_id = vmr.val_id
left join (
select vsmr.main_id, vs.val, vs.date_, vs.hour
from val_sub_main_rel vsmr
join val_sub vs on vs.val_sub_id = vsmr.val_sub_id
) vsx on vsx.main_id = m.main_id
and vsx.date_ = v.date_
and vsx.hour = v.hour;
获得看起来更合理的输出:
MAIN_ID ORIG_VAL SUB_VAL UNITS HOUR DATE_
---------- ---------- ---------- ------ -------- ----------
2 -87 12 LBs 01:00 AM 2018-11-30
2 8 13 LBs 02:00 AM 2018-11-30
1 18 INches 03:00 AM 2018-11-30