如果你是在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
但既然你都没有,你可以伪造的。从this site适应:
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
正在改变行转换成列;在10克你只需要自己做。 SELECT ... CONNECT BY ...
只是生成一个虚拟值列表,并且这必须足以覆盖要转换为行的列数(如果真的有1000个,则应该重新访问数据模型)。这两个decode
语句使用生成的数字来匹配列名和值 - 自己运行内部选择以查看看起来像什么。
不诉诸动态SQL,你不能脱离必须列出列 - 只有一次真正unpivot
,但假冒10g版本两次,你必须确保它们匹配正确,并且行号发生器正在产生足够的值。 (太多了,你可能会得到奇怪的结果,但因为任何额外的值将在这里为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
可能重复的[将行转换为oracle10g中的列](http://stackoverflow.com/questions/3512140/convert-row-into-columns-in- oracle10g) – Ollie 2012-07-26 12:19:50
[Oracle Columns to Rows]的可能重复(http://stackoverflow.com/questions/867737/oracle-columns-to-rows) – 2012-07-27 14:41:38