sql >> データベース >  >> RDS >> Oracle

Oracle10G SQL:列を行に変換する

    11Gを使用している場合は、unpivot

    SELECT subject, AVG(percentage) AS percentage
    FROM (
        SELECT * FROM tablea
        UNPIVOT (percentage FOR subject IN (math, science, computer))
    )
    GROUP BY subject
    ORDER BY subject;
    
    SUBJECT  PERCENTAGE
    -------- ----------
    COMPUTER      94.33
    MATH          91.33
    SCIENCE       87.33
    

    しかし、あなたはそうではないので、あなたはそれを偽造することができます。 このサイト> :

    SELECT subject, AVG(percentage) AS percentage
    FROM (
        SELECT DECODE(unpivot_row, 1, 'Math',
                                   2, 'Science',
                                   3, 'Computer') AS subject,
               DECODE(unpivot_row, 1, math,
                                   2, science,
                                   3, computer) AS percentage
        FROM tablea
        CROSS JOIN (SELECT level AS unpivot_row FROM dual CONNECT BY level <= 3)
    )
    GROUP BY subject
    ORDER BY subject;
    
    SUBJECT  PERCENTAGE
    -------- ----------
    Computer      94.33
    Math          91.33
    Science       87.33
    

    どちらの場合も、内側のselect 行を列に変換しています。 10gでは自分でやるだけです。 SELECT ... CONNECT BY ... ダミー値のリストを生成するだけで、これは行に変換する列の数をカバーするのに十分でなければなりません(実際に1000がある場合は、データモデルを再検討する必要があります)。 2つのdecode ステートメントは、生成された数値を使用して列の名前と値を照合します。内部選択を単独で実行して、どのように表示されるかを確認します。

    動的SQLに頼らなければ、列をリストする必要がなくなります。実際のunpivotで1回だけです。 、ただし、偽の10gバージョンでは2回です。これらが適切に一致していること、および行番号ジェネレーターが十分な値を生成していることを確認する必要があります。 (多すぎると奇妙な結果が得られる可能性がありますが、ここでは余分な値がnullになり、avgを使用しているためです。 、この場合はそれほど重要ではありません。健全性チェックと同じように、とにかく完全に一致させる必要があります。

    または、name以外のすべての列が常に必要であることに基づく別のバージョン 、つまり、必要な列を1回だけリストする必要があり、視覚的に一致させるのが簡単です。whenを追加し続けるだけです。 条項;行数は必要ありません:

    SELECT subject, AVG(percentage) AS percentage
    FROM (
        SELECT column_name AS subject,
            CASE
                WHEN column_name = 'MATH' then math
                WHEN column_name = 'SCIENCE' then science
                WHEN column_name = 'COMPUTER' then computer
            END AS percentage
        FROM tablea
        CROSS JOIN (
            SELECT column_name
            FROM user_tab_columns
            WHERE table_name = 'TABLEA'
            AND column_name != 'NAME'
        )
    )
    GROUP BY subject
    ORDER BY subject;
    
    SUBJECT                        PERCENTAGE
    ------------------------------ ----------
    COMPUTER                            94.33
    MATH                                91.33
    SCIENCE                             87.33
    



    1. OBJECTPROPERTY()関数を使用して、オブジェクトがSQL Serverのテーブル、ビュー、またはストアドプロシージャであるかどうかを確認します

    2. SQLピボットテーブルダイナミック

    3. MariaDBでのPERIOD_ADD()のしくみ

    4. com.mysql.jdbc.MysqlDataTruncation:データの切り捨て:データが列'column_name'に対して長すぎます