不使用 SWITCH CASE 的条件操作

Conditional operations without using SWITCH CASE

我有几个复杂的表格。但是他们的映射是这样的:

TABLE_A:

_________________________________
|   LINK_ID     |   TYPE_ID     |
_________________________________
| adfasdnf23454 |   TYPE 1      |
| 43fsdfsdcxsh7 |   TYPE 1      |
| dfkng037sdfbd |   TYPE 1      |
| sd09734fdfhsf |   TYPE 2      |
| khsadf94u5dfc |   TYPE 2      |
| piukvih66wfa8 |   TYPE 3      |
_________________________________

TABLE_B:

_____________________________________________
|   LINK_ID     |  CODE_ID  | CODE_VALUE    |
_____________________________________________
| adfasdnf23454 |    7      |   test 1      |
| fgubk65esdfj7 |    6      |   test 2      |
| ooogfsg354fds |    7      |   test 3      |
| sd09734fdfhsf |    5      |   test 4      |
_____________________________________________

LINK_ID 列链接这两个表。

我的要求是检查 TABLE_A 中的所有记录是否具有特定的 CODE_ID与否。

  1. 如果记录有 CODE_ID 作为 7 - 在列中填充 CODE_VALUE
  2. 如果记录有 CODE_ID 作为 6 - 在另一列中填充 CODE_VALUE
  3. 如果记录没有 CODE_ID 显示 CODE_VALUE 为空。

问题是,TABLE_B 可能有 TABLE_A 没有的记录。但是最终结果应该只包含TABLE_A的记录。

PS:不建议使用 SWITCH CASE,因为我需要同一行中的字段。 (请在使用 SWITCH CASE 的 OBTAINED RESULT 中查看相同 LINK_ID 的多行)

获得的结果

_______________________________________________
|   LINK_ID     | CODE_VALUE_1 | CODE_VALUE_1 |
_______________________________________________
| adfasdnf23454 |   test 1     |    null      |
| adfasdnf23454 |   null       |    test 4    |
| sd09734fdfhsf |   test 6     |    null      |
_______________________________________________

预期结果

__________________________________________________
|   LINK_ID     | CODE_VALUE_1  |   CODE_VALUE_2 |
__________________________________________________
| adfasdnf23454 |   test 1      |   test 4       |
| 43fsdfsdcxsh7 |   null        |   null         |
| dfkng037sdfbd |   null        |   null         |
| sd09734fdfhsf |   test 6      |   null         |
| khsadf94u5dfc |   null        |   null         |
| piukvih66wfa8 |   null        |   null         |
__________________________________________________

有人可以帮忙吗?

一个选项使用两个相关的子查询:

select
    a.link_id,
    (select code_value from table_b b where b.link_id = a.link_id and b.code_id = 7) code_value_1,
    (select code_value from table_b b where b.link_id = a.link_id and b.code_id = 6) code_value_2
from table_a a

请注意,这假定 table_b 中没有重复的 (link_id, code_id)。你也可以用两个 left joins 来写这个——这是完全相同的逻辑。

另一种方案是单left join,然后条件聚合:

select  
    a.link_id,
    max(case when b.code_id = 7 then b.code_value end) code_value_1,
    max(case when b.code_id = 6 then b.code_value end) code_value_2
from table_a a
left join table_b b on b.link_id = a.link_id and b.code_id in (6, 7)
group by a.link_id

你问题的问题部分是如果 B 中的两个条目具有相同的 link_id 和 type_id 该怎么办。您可以使用最小值、最大值、最后一个条目(但为此您需要 B 中的排序列)。或者您可以将它们全部列出:

select * 
from a left join b using (link_id) 
pivot (listagg(code_value, ', ') within group (order by code_value) 
       for code_id in (6 as code6, 7 as code7))

数据:

create table a (link_id, type_id) as (
  select 'a', 'TYPE 1' from dual union all
  select 'b', 'TYPE 1' from dual union all
  select 'c', 'TYPE 1' from dual union all
  select 'd', 'TYPE 2' from dual );

create table b(LINK_ID, CODE_ID, CODE_VALUE) as (
  select 'a',    6, 'test 1' from dual union all
  select 'a',    7, 'test 2' from dual union all
  select 'a',    7, 'test 3' from dual union all
  select 'b',    7, 'test 4' from dual union all
  select 'd',    6, 'test 5' from dual );

结果:

LINK_ID  TYPE_ID  CODE6     CODE7
a        TYPE 1   test 1    test 2, test 3
b        TYPE 1             test 4
c        TYPE 1
d        TYPE 2   test 5

dbfiddle