2012-03-16 10 views
0

私はデータ変換

 

ID  Field1  Field2 Field3 
1  A   B   C 
1  G 
1  H 
2  F   D   E 

を以下にそれを変換したい

 

ID  Field1  Field2 Field3 
1  A 
1     B 
1       C 
2     D 
2       E 
2  F 
1  G 
1  H 

テーブル内のデータをSQLを使用して行うことができ、この何かがあるか、私はPLに行くことにしている、次のしています/ SQL? 私がここで期待するデータは何百万ものものなので、私はCROSS JOINにパスを与えたいと思います。

+0

そのテーブルに主キーがありますか?テーブルのデータを変更する(Update + Delete)か、単純に選択しますか? – xanatos

+3

@ASolvent:BとCはAと同じ行に返されますが、GやHは返されないのはなぜですか?これを決定する別の列(表示されていない列)がありますか? –

+0

OMG-以前は似たような状況でしたが、データが100(s)だったので、データをフロントエンドに送り、そこで簡単に操作しました。私はカーソルでそれを行うことができます。 – asolvent

答えて

1

次のSELECT文を使用すると、一部の行を集約できます。

select ID, min(Field1) Field1, min(Field2) Field2, min(Field3) Field3 
    from your_table 
    group by ID 
    -- Ignore rows where this would lose data 
    having nvl(count(Field1),0) < 2 
     and nvl(count(Field2),0) < 2 
     and nvl(count(Field3),0) < 2 

テストデータで実行すると、次の結果が得られます。

ID FIELD1 FIELD2 FIELD3 
----- ------ ------ ------ 
    2 F  D  E 

これをPL/SQLでループし、IDを持つすべての行を削除し、このデータを1行挿入できます。

おそらく、第2パスでfirst_value関数を使用できます。

私の本能は、この表が適切に正規化されていない可能性があることを示唆しています。多分あなたは別のテーブルを持っているべきです。これは、このクエリの結果のようになります。

select id, 'Field1' field_id, Field1 field_value 
    from your_table 
    where field1 is not null 
union 
select id, 'Field2' field_id, Field2 field_value 
    from your_table 
    where field2 is not null 
union 
select id, 'Field3' field_id, Field3 field_value 
    from your_table 
    where field3 is not null 
order by 1, 2, 3 
/

    ID FIELD_ F 
---- ------ - 
    1 Field1 A 
    1 Field1 G 
    1 Field1 H 
    1 Field2 B 
    1 Field3 C 
    2 Field1 F 
    2 Field2 D 
    2 Field3 E 

あなたがテーブルを再正規化することができない場合は、PL/SQL内の同じ(正規化)クエリをループしてみてください。各フィールドにスタックがあり、各行の値をプッシュします。 IDが変わったら、各スタックからフィールド1,2,3をポップし、ヌルで埋めて、3つのスタックすべてが使い果たされるまで繰り返して、行を作成します。

この情報が役立ちますようにお願いいたします。