【问题标题】:Oracle SQL : Need help how below can be fetchedOracle SQL:需要帮助如何获取以下内容
【发布时间】:2019-06-12 19:26:20
【问题描述】:

我有 2 张桌子。一个是数据表,另一个是映射表。映射表包含 TYPE、ATTRIBUTE 和 DESTINATION 等字段。映射表告诉,对于特定的 TYPE,哪个属性出现在数据表的哪个列中

数据表

TYPE    Data_field1    data_field2   data_field3  
-------------------------------------------------
abc       1234           5678         4321         
def       5679           1235         9877          

映射表

TYPE     Attribute    destination
--------------------------------------
abc      emp_id           data_field1
abc      dept_id          data_field2
abc      ph_no            data_field3 
def      emp_id           data_field2
def      dept_id          data_field3
def      ph_no            data_field1

我想要如下结果,

结果表

Type     emp_id    dept_id    ph_no
------------------------------------------------
abc      1234       5678      4321
def      1235       9877      5679

我尝试如下,

Select Case when type='abc' then data_field1 
            when type='def' then data_field2 end emp_id,
       case when type='abc' then data_field2
            when type='def' then data_field3 end dept_id,
       case when type='abc' then data_field3
            when type='def' then data_field1 end ph_no
from data_table;

我从 MAPPING_TABLE 中手动检查了特定 ATTRIBUTE 的 TYPE 和 DESTINATION 并进行了上述查询。问题是我有超过 50 种类型,每种类型都有近 100 个属性。所以我无法对所有类型进行上述查询。

所以期待一个简单或更好的解决方案

提前致谢

【问题讨论】:

  • 也许使用某种 PIVOT,但这不是一个很好的表格设计。
  • 如果对于像“def”这样的另一种类型,属性和目标之间存在不同的映射,那么结果应该是什么。假设“def”的映射是 ph_no --> Data_field1,在这种情况下您期望什么?还有一件事,所有类型都有相同的属性吗?您能否编辑您的问题以使其仅适用于 3 Data_field 和 3 TYPE 以及您的预期结果?
  • 你是 ryt Tejash。只有我拥有的确切情况。感谢您的建议。编辑了我的问题。

标签: sql oracle etl


【解决方案1】:

同意上述 cmets 认为这不是一个好的表设计,但是如果您别无选择,只能使用它,那么我倾向于使用动态 SQL 解决方案(以下未经测试,可能包含语法错误,但应该是一个很好的起点)。

此解决方案假定所有类型都具有相同的字段(并且所有类型都将具有所有字段的定义)。

使用下面的方法构建字符串后,您可以使用 execute immediate 将其选择为表类型,或在循环中使用它来迭代,或者您需要对其执行的任何其他操作。

declare
  v_sql_string varchar2(32000);
  v_first_row boolean default true;      
  v_current_type varchar2(3) default null;

  cursor c_types is 
  select * from mapping_table
  order by type, attribute;

begin
  for v_row in c_mappings loop
    if v_fisrt_row then
       v_sql_string := 'Select ';
       v_current_type := v_row.type;
    else 
       if v_curent_type != v_row.type then           
         v_sql_string := 'Union select ';
       end if;
    end if;

    if v_first_row then
      v_sql_string := v_sql_string || ' as ' || attribute ';
    else
      v_sql_string := ', ' || v_sql_string || ' as ' || attribute ';
    end if;
  end loop;
  dbms_output.put_line(v_sql_string);  
end;
/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-11
    • 2013-09-07
    • 2019-12-27
    • 2012-09-26
    相关资源
    最近更新 更多