2013-07-14 3 views
-1

"범위"라는 필드 하나에 COUNTRY | JOB_CD | AGE와 같은 파이프 구분 기호로 구분 된 하나 또는 여러 개의 특성이 포함 된 테이블이 있습니다. 이러한 특성은 테이블 별칭 이름과 매핑을 가진 다른 테이블에서 개별적으로 정의되며 이전 테이블의 별칭을 사용하여 이러한 특성이 개별적으로 속한 실제 테이블 이름을 제공합니다.다른 테이블에서 사람의 속성을 가져 오기위한 SQL 쿼리

기준에 속한 모든 사람 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로이 모든 아래

이 필요한 몇 가지 기록했다. 당신은 당신이 어떤 다른 테이블에이 shonky CSV 테이블의 출력을 결합하는 방법을

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 
+4

, 제발, 제발 - 테이블을 정상화를 ... 그러면 훨씬 쉬운 작업이됩니다. – sgeddes

+0

현재이 이전 프로젝트에서 이러한 향상을 수행 할 수 없습니다. ( –

+0

첫 번째, 두 번째 두 테이블은 어떻게 문제에 매핑됩니까? 질문하는 질문은 "단지"첫 번째 테이블의 데이터 구문 분석이 필요합니다. , 당신은 3 개의 테이블 모두에 공통의'person_id' 필드가 있지만 두 번째 또는 세 번째 테이블에'person_id' 컬럼을 표시하지 않는다고 말합니다 –

답변

0

당신은 아직도 분명히하지 않았다. 따라서이 솔루션은 문제의 해당 부분을 무시합니다. 추가 지침이 필요한 경우 요구 사항에 대한 추가 정보를 제공해야합니다.

해가 하나의 솔루션입니다. 그것은 파이프 라인 기능을 사용합니다.이 기능은 반드시 가장 뛰어난 옵션은 아니지만, 내가 말했듯이 상황이 너무 엉망이되어서, "빨리 작동합니다"이상의 "작동"해야합니다.

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> 
+0

APC에 도움을 주셔서 감사합니다. 한 번 봐 주시면 감사하겠습니다. –

+0

감사의 말에 감사드립니다. 감사합니다! –

관련 문제