I need to turn columns into rows and get its average.
For example I have this table:
Name Math Science Computer
---- ---- ------- --------
Ted 90 89 95
Zed 99 98 98
Fed 85 75 90
The output should be:
Subject Average
------- -------
Math 88
Science 87.33
Computer 94.33
How can I achieve it? Thank you for the help.
If you were on 11G you could use
unpivot:But since you are not, you can fake it. Adapting from this site:
In both cases, the inner
selectis transforming rows into columns; in 10g you just have to do it yourself. TheSELECT ... CONNECT BY ...just generates a list of dummy values, and this has to have enough to cover the number of columns you are converting to rows (and if you really have 1000, you should really revisit the data model). The twodecodestatements use that generated number to match up a column name and value – run the inner select on its own to se what that looks like.Without resorting to dynamic SQL, you can’t get away from having to list the columns – only once with the real
unpivot, but twice with the fake 10g version, and you have to make sure they match up properly, and that the row number generator is producing enough values. (Too many and you might get odd results, but as any extra values will be null here and you’re usingavg, it doesn’t matter too much in this case; just as a sanity check you should probably make it match exactly anyway).Or another version, based on you always wanting all the columns except
name, which means you only need to list the columns you do want once and it’s easier to match them up visually – just keep addingwhenclauses; and you don’t need the row count: