如果你是在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