用于从不同表中获取人员属性的SQL查询

时间:2013-07-14 04:42:04

标签: sql oracle oracle10g

我有一个表,其中我们有一个名为“scope”的字段包含由管道分隔符分隔的单个或多个属性,如COUNTRY | JOB_CD | AGE。这些属性在另一个表中单独定义,该表具有表别名的映射,另一个表使用上一个表中的别名为您提供这些属性分别属于的真实表名。

我必须在读取范围值后创建一个查询,该范围值检索属于标准的所有人ID意味着“获取所有居住在美国的用户,其中JOB_CD为23且年龄为30” 由于我们在一个表中没有所有人员属性/属性,如何有效地实现这一点。请帮助。

PERSONID    SCOPE                  COMP_VALUE
------------------------------------------------------------------------
1234        COUNTRY|JOB_CD |AGE    USA|23|30


ELEMENT CD  ALIAS
-----------------------------
COUNTRY EA  
JOB_CD  EJ
AGE     EATTR


ALIAS   TABLE_NM
-----------------------------------
EA      EMP_ADDRESS
EJ      EMP_JOB
EATTR   EMP_ATTRIB

上面的表格中有更多列,但我发布了一些我需要的列

以下所有表格都有一个共同的字段person_id。

EMP_ADDRESS Table have below column
-------------------------
PERSON_ID
COUNTRY

EMP_JOB Table have below column
-------------------------
PERSON_ID
JOB_CD


EMP_ATTRIB Table have below column
-------------------------
PERSON_ID
AGE

1 个答案:

答案 0 :(得分:0)

您仍然没有说明如何将此shonky CSV表的输出加入到您拥有的其他表中。所以这个解决方案忽略了这部分问题。如果您需要额外的指导,您需要提供有关您的要求的更多信息。

她是一个解决方案。它使用了流水线功能,这不一定是最高性能的选项,但就像我说的那样,你的情况如此混乱,你必须把“它工作”比“它工作得很快”。

Pipelined函数返回一个嵌套表:

create or replace type bp_record as object
( element varchar2(30)
  , table_name varchar2(30)
  , value varchar2(30) );
/

create or replace type bp_recs as table of bp_record;
/

流水线功能本身:

create or replace function bp_cannon 
  ( p_id in your_table.personid%type)
  return bp_recs pipelined
is
    return_value bp_record := new bp_record (null,null,null);
    lrec your_table%rowtype;
    s_offset pls_integer := 1;
    s_nxt pls_integer; 
    c_offset pls_integer := 1;
    c_nxt pls_integer; 
begin
    select personid, concat(scope, '|'), concat(comp_value, '|') 
    into lrec 
    from your_table
    where personid = p_id;

    loop
        s_nxt := instr(lrec.scope, '|', s_offset);
        if s_nxt = 0 then exit; end if;
        return_value.element := trim(substr(lrec.scope, s_offset, s_nxt-s_offset));

        select tl.table_nm
        into return_value.table_name
        from element_lookup el
            join table_lookup tl 
            on ( tl.alias = el.alias)
        where el.element = return_value.element;

        c_nxt := instr(lrec.comp_value, '|', c_offset);
        return_value.value := trim(substr(lrec.comp_value, c_offset, c_nxt-c_offset));

        pipe row (return_value);

        s_offset := s_nxt + 1;
        c_offset := c_nxt + 1;
    end loop;

    return;
end bp_cannon;
/

行动中:

SQL> select * from table (bp_cannon(1234))
  2  /

ELEMENT                        TABLE_NAME                     VALUE
------------------------------ ------------------------------ ------------------------------
COUNTRY                        EMP_ADDRESS                    USA
JOB_CD                         EMP_JOB                        23
AGE                            EMP_ATTRIB                     30

SQL>