1

列を行に変換し、その平均を取得する必要があります。

たとえば、次のテーブルがあります。

Name   Math    Science     Computer
----   ----    -------     --------
Ted    90       89          95
Zed    99       98          98
Fed    85       75          90

出力は次のようになります。

Subject      Average
-------      -------
Math         88
Science      87.33
Computer     94.33

どうすれば達成できますか?お手伝いありがとう。

4

1 に答える 1

2

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 に頼らなければ、列をリストする必要から逃れることはできません。本物の 10g バージョンでは 1 回だけunpivotですが、偽の 10g バージョンでは 2 回です。十分な価値を生み出しています。(多すぎると奇妙な結果が得られる可能性がありますが、ここでは余分な値が null になり、 を使用してavgいるため、この場合はあまり問題になりません。サニティ チェックと同様に、とにかく正確に一致させる必要があります) .


または、常に を除くすべての列nameが必要であることに基づいた別のバージョンです。つまり、必要な列を一度だけリストする必要があり、それらを視覚的に一致させる方が簡単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
于 2012-07-25T08:29:47.850 に答える