2016-10-20 3 views
0

오라클의 여러 열에서 쉼표로 구분 된 값을 행으로 변환하는 테이블에서보기를 만들려고합니다.여러 열에서 행으로 쉼표로 구분 된 값 변환

하나의 열에 대해이 작업을 성공적으로 수행했습니다. 그러나 나는 두세 개의 열에 대해 그것을 할 수 없다.

하나의 열에 대해 성공적으로 실행되는 다음 스크립트를 사용했습니다.

Create VIEW MULTITESET AS 
SELECT rownum AS ID1,Tagging.COMMENTS,Tagging.category,Tagging.STATUS, 
     trim(regexp_substr(Tagging.OBJ_ID, '[^,]+', 1, lines.column_value)) OBJ_ID 
    FROM Tagging, 
     TABLE (CAST (MULTISET 
     (SELECT LEVEL FROM dual 
       CONNECT BY instr(Tagging.OBJ_ID, ',', 1, LEVEL - 1) > 0 
    ) AS sys.odciNumberList)) lines 
    ORDER BY id, lines.column_value 

는 지금은 열 OBJ_ID에 대한 등 OBJname라는 이름의 두 번째 열에 대해 동일한 작업을 수행해야합니다.

그래서 나는 다음과 같이 바보 같은 것을 시도했다.

Create VIEW MULTITESET AS 
SELECT rownum AS ID1,Tagging.COMMENTS,Tagging.category,Tagging.STATUS, 
     trim(regexp_substr(Tagging.OBJ_ID, '[^,]+', 1, lines.column_value)) OBJ_ID 
    FROM Tagging, 
     TABLE (CAST (MULTISET 
     (SELECT LEVEL FROM dual 
       CONNECT BY instr(Tagging.OBJ_ID, ',', 1, LEVEL - 1) > 0 
    ) AS sys.odciNumberList)) lines 
    ORDER BY id, lines.column_value , 
    trim(regexp_substr(Tagging.OBJname , '[^,]+', 1, lines.column_value)) OBJname 
    FROM Tagging, 
     TABLE (CAST (MULTISET 
     (SELECT LEVEL FROM dual 
       CONNECT BY instr(Tagging.OBJname , ',', 1, LEVEL - 1) > 0 
    ) AS sys.odciNumberList)) lines 
    ORDER BY id, lines.column_value 

너트 쉘에서는 아래 그림의 tabel-A를 table-B로 변환하고 싶습니다. 어떻게해야합니까?

See attached picture

내 실제보기 쿼리는 다음과 같습니다

SELECT rownum AS TRACKID2, LEAPFROG_TAGGING.ID, LEAPFROG_TAGGING.CREATED_DATE, 
    LEAPFROG_TAGGING.CREATED_BY, LEAPFROG_TAGGING.COMMENTS, 
    leapfrog_tagging.category, LEAPFROG_TAGGING.STATUS, LEAPFROG_TAGGING.OBJ_NAME, 
    trim(regexp_substr(LEAPFROG_TAGGING.OBJ_ID, '[^,]+', 1, lines.column_value)) OBJ_ID 
FROM LEAPFROG_TAGGING, 
TABLE (CAST (MULTISET (
    SELECT LEVEL FROM dual 
    CONNECT BY instr(LEAPFROG_TAGGING.OBJ_ID, ',', 1, LEVEL - 1) > 0 
) AS sys.odciNumberList)) lines 
ORDER BY id, lines.column_value; 

답변

1

은 항상 두 개의 열 (ID 당 그래서 정확히 하나 개의 이름)과 일치하는 쉼표로 구분 된 값의 수를 가정하면, 당신이 걸 11gR2에서, 당신은 recursive subquery factoring를 사용할 수 있습니다

create view multiteset as 
with t (obj_id, obj_name, status, other_columns, rn, orig_obj_id, orig_obj_name) as (
    select regexp_substr(obj_id, '[^,]+', 1, 1), 
    regexp_substr(obj_name, '[^,]+', 1, 1), 
    status, other_columns, 1, obj_id, obj_name 
    from tagging 
    union all 
    select regexp_substr(orig_obj_id, '[^,]+', 1, rn + 1), 
    regexp_substr(orig_obj_name, '[^,]+', 1, rn + 1), 
    status, other_columns, rn + 1, orig_obj_id, orig_obj_name 
    from t 
    where rn < regexp_count(orig_obj_id, '[^,]+') 
) 
select obj_id, obj_name, status, other_columns 
from t; 

select * from multiteset; 

OBJ_ID      OBJ_NAME STATUS OTHER_ 
---------------------------- -------- ------ ------ 
1       a  open value1 
1       a  closed value2 
4       hj  na  value3 
2       s  open value1 
2       s  closed value2 
5       hj  na  value3 
3       d  open value1 
6       hj  na  value3 
4       f  open value1 
7       hj  na  value3 

10 rows selected. 

열 이름을 귀하의 질문에 약간의 일치로 당신이 당신의 연구를 조정해야하므로 이름.

앵커 멤버는 각 목록에서 첫 번째 요소를 가져오고 원래 목록의 복사본과 현재 어떤 요소가 있는지 (1부터 시작) 볼 수있는 카운터를 유지합니다.

다음 재귀 멤버는 각 목록에서 다음 (rn +) 요소를 찾아 카운터에서 따로 변경되지 않은 나머지 값을 전달합니다.

CTE에 대한 마지막 쿼리가 다음 바로 CTE 당신이 의견에 추가 된 새로운 원본 뷰 정의에서의 트랙 (rn, orig_obj_id 등)

를 유지 한 임시 사람을 무시하고, 생성 된 값을 얻는다, 당신은 정말 할 수 있습니다 :

create view multiteset as 
with t (id, created_date, created_by, comments, category, status, 
    obj_name, obj_id, rn, orig_obj_name, orig_obj_id) 
as (
    select id, created_date, created_by, comments, category, status, 
    regexp_substr(obj_name, '[^,]+', 1, 1), 
    regexp_substr(obj_id, '[^,]+', 1, 1), 
    1, obj_name, obj_id 
    from leapfrog_tagging 
    union all 
    select id, created_date, created_by, comments, category, status, 
    regexp_substr(orig_obj_name, '[^,]+', 1, rn + 1), 
    regexp_substr(orig_obj_id, '[^,]+', 1, rn + 1), 
    rn + 1, orig_obj_name, orig_obj_id 
    from t 
    where rn < regexp_count(orig_obj_id, '[^,]+') 
) 
select id, created_date, created_by, comments, category, status, 
    obj_name, obj_id 
from t; 

은 또한 더 order by 조항이없는 알; 그건 정말 뷰 정의에 이해가되지 않으며, 대신 뷰 쿼리 할 때 적용되어야한다 : 당신이 그렇게보기 resulsts 다음뿐만 아니라 그 발주 할 수있는 위치 마커를 유지하려면

select * from multiteset order by id, obj_id; 

... 
select id, rn as trackid2, created_date, created_by, comments, category, status, 
    obj_name, obj_id 
from t; 

당신을 할 것이다 :

select * from multiteset order by id, trackid2; 
+0

감사 알렉스 (! 또는 더 의미있는 이름)의 최종 선택 목록에서, 예를 들어 rn을 포함한다. 나는 이것을 시도했다. 하지만 난 "02000 오류가 발생했습니다.00000 - " –

+0

내 실제보기는"%의 키워드 누락 " TRACKID2 AS SELECT ROWNUM, LEAPFROG_TAGGING.ID, LEAPFROG_TAGGING.CREATED_DATE, LEAPFROG_TAGGING.CREATED_BY, LEAPFROG_TAGGING.COMMENTS, leapfrog_tagging.category, AS VIEW를 만들 LEAPFROG_TAGGING.STATUS, LEAPFROG_TAGGING.OBJ_NAME, 트림 (REGEXP_SUBSTR (LEAPFROG_TAGGING.OBJ_ID '[^] +'1 lines.column_value)) OBJ_ID LEAPFROG_TAGGING FROM , TABLE (CAST는 (MULTISET 은 (존재하는 레벨을 선택 이중 연결 번호가 instr (LEAPFROG_TAGGING.OBJ_ID, ',', 1, LEVEL - 1)> 0 ) AS sys.odciNumberList)) 행 ORDER BY id, lines.column_value; –

+0

'CREATE VIEW AS SELECT'에 새보기의 이름이 누락되었습니다. 그러나 주석에 코드를 덤프하지 마십시오. 읽기가 정말 어렵습니다. 관련성이있는 경우 질문을 수정하십시오. 해당 코드가 누락 된 키워드를 얻거나 내 대답에 코드를 실행합니까? 아마도 당신은 아마도 약간 수정해야만했을 것입니다. –

관련 문제