2016-10-20 23 views
0

私は、複数の列の昏睡区切りの値をOracleの行に変換する表からビューを作成しようとしています。複数の列から行への昏睡区切り値の変換

これを1つの列に対して正常に実行しました。しかし私は2つまたは3つの列のためにそれを行うことができません。

1つの列に対して正常に実行される以下のスクリプトを使用しました。

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 

ナッツシェルでは、下の図のテーブルAをテーブル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

は、カンマで区切られた値の数が常に2つの列(IDあたりので、正確に1名)に一致し、あなたがしていると仮定すると、 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. 

カラム名を、あなたの質問に少し矛盾するよう、あなたのRを調整する必要がありますので、名前。

アンカーメンバーは、各リストから最初の要素を取得し、元のリストのコピーを保持し、現在の要素(1から始まる)を確認するカウンタを保持します。

再帰メンバは、各リストの次の要素(rn +)を検索し、残りの値を変更せずにカウンターから渡します。

CTEに対して、最終的なクエリはその後、ちょうどCTEは、あなたがコメントで追加された新しいオリジナルのビュー定義からのトラック(rnorig_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句がありません注意してください。それは本当にビュー定義では意味がない、とあなたの代わりにビューを照会する際に適用する必要があります。

select * from multiteset order by id, obj_id; 

あなたがポジションマーカーを維持したい場合はそのビューresulstsは、その後、同様にそのことにより、注文することができます含まrn(またはそれ以上の意味のある名前!)最後の選択リストで、例えば:

あなたを聞かせ
... 
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

感謝アレックス。 私はこれを試しました。しかし、私はエラー02000を取得しました。00000 - 「 –

+0

私の実際のビューがある "%sのキーワードが欠落している" TRACKID2 AS SELECT ROWNUM、 LEAPFROG_TAGGING.ID、 LEAPFROG_TAGGING.CREATED_DATE、 LEAPFROG_TAGGING.CREATED_BY、 LEAPFROG_TAGGING.COMMENTS、 leapfrog_tagging.category、 AS VIEWのCREATE LEAPFROG_TAGGING FROM LEAPFROG_TAGGING.STATUS、 LEAPFROG_TAGGING.OBJ_NAME、 トリム(REGEXP_SUBSTR(LEAPFROG_TAGGING.OBJ_ID、 '[^、] +'、1、lines.column_value))OBJ_ID 、 表(CAST(MULTISET (からのレベル を選択デュアル CONNECT BY instr(LEAPFROG_TAGGING.OBJ_ID、 '、'、1、LEVEL - 1)> 0 )AS sys.odciNumberList))行 ORDER BY id、 lines.column_value; –

+0

'CREATE VIEW AS SELECT'に新しいビューの名前がありません。しかし、コメントにコードをダンプしないでください。本当に読みにくいです。それが関連している場合は、質問を編集してください...そのコードは不足しているキーワードを取得するか、答えにコードを実行しますか?おそらくあなたはかなり修正する必要がありました。 –

関連する問題