Oracle Database Query跨越两个表,从交叉列

时间:2018-02-07 16:28:46

标签: sql oracle

创建跨越两个表的查询并从交叉列中选择最高权重时遇到一些困难(在dP1和tP1,dP2和tP2,dP3和tP3之间)。

  • 如果在表DETAILS中我收到dP1,dP2和dP3,我必须选择TEMPATE,其中tP1 = dP1,tP2 = dP2,tP3 = tP3。
  • 未找到记录,然后选择TEMPLATE,tP1 = dP1,tP2 = dP2。
  • 未找到记录,然后选择TEMPLATE tP1 = dP1。
  • 未找到任何记录,然后选择与PX无关的模板。

注意:dPX是有序的,这意味着我只接收DETAILS dP1,或dP1 + dP2或dP1 + dP2 + dP3。如果我只收到一个dP2,我将寻找与PX无关的模板。

示例

表详细信息

| BATCH_ID | TEMPLATE_ID | dP1 | dP2 | dP3 |
| 12345 | template_1 | a | b | c |
| 12345 | template_1 | a | b | |
| 12345 | template_1 | a | | |
| 12345 | template_1 | | | |
| 12345 | template_1 | x | | |
| 12345 | template_1 | | y | |
| 12345 | template_1 | a | z | |

表格模板

| TEMPLATE_ID | MESSAGE | tP1 | tP2 | tP3 |
| template_1 | msg0 | | | |
| template_1 | msg1 | a | | |
| template_1 | msg2 | a | b | |
| template_1 | msg3 | a | b | c |

将BATCH_ID作为输入,我希望像这样返回查询:

select * from DETAILS d left join TEMPLATE t on d.TEMPLATE_ID=t.TEMPLATE_ID where BATCH_ID='12345'和....

| TEMPLATE_ID | MESSAGE | dP1 | dP2 | dP3 | tP1 | tP2 | tP3 |
| template_1 | msg0 | | | | | | |
| template_1 | msg1 | a | | | a | | |
| template_1 | msg2 | a | b | | a | b | |
| template_1 | msg3 | a | b | c | a | b | c |
| template_1 | msg0 | x | | | | | |
| template_1 | msg0 | | y | | | | |
| template_1 | msg1 | a | z | | a | | |

感谢任何帮助。谢谢你的关注。

1 个答案:

答案 0 :(得分:0)

编辑:使用更正的逻辑和更高的成本进行更新。我非常确定有更好的方式来编写优先级部分,但我需要更多咖啡。

select template_id, message, 
    dp1, dp2, dp3, 
    tp1, tp2, tp3
from ( select d.template_id, message, 
    dp1, dp2, dp3, 
    tp1, tp2, tp3,
    case when (dp1 = tp1 and dp2 = tp2 and dp3 = tp3) then 1
         when (dp1 = tp1 and dp2 = tp2 and tp3 is null) then 2
         when (dp1 = tp1 and tp2 is null and tp3 is null) then 3
         when coalesce(tp1,tp2,tp3) is null then 4
         else 5 end as tpriority,
    min(case when (dp1 = tp1 and dp2 = tp2 and dp3 = tp3) then 1
         when (dp1 = tp1 and dp2 = tp2 and tp3 is null) then 2
         when (dp1 = tp1 and tp2 is null and tp3 is null) then 3
         when coalesce(tp1,tp2,tp3) is null then 4
         else 5 end) over (partition by d.template_id, dp1, dp2, dp3) as min_priority
    from DETAILS d
    left join TEMPLATE t
        on d.TEMPLATE_ID = t.TEMPLATE_ID (+)
) v
where tpriority = min_priority
;

输出

TEMPLATE_ID                    MESSAGE    DP1 DP2 DP3 TP1 TP2 TP3
------------------------------ ---------- --- --- --- --- --- ---
template1                      msg3       a   b   c   a   b   c  
template1                      msg2       a   b       a   b      
template1                      msg1       a   z       a          
template1                      msg1       a           a          
template1                      msg0       x                      
template1                      msg0           y                  
template1                      msg0