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