Jeśli korzystałeś z 11G, możesz użyć 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
Ale skoro nie jesteś, możesz to udawać. Adaptacja z tej strony :
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
W obu przypadkach wewnętrzny select
przekształca wiersze w kolumny; w 10g po prostu musisz zrobić to sam. SELECT ... CONNECT BY ...
po prostu generuje listę fikcyjnych wartości, a to musi wystarczyć, aby pokryć liczbę kolumn, które konwertujesz na wiersze (a jeśli naprawdę masz 1000, naprawdę powinieneś ponownie odwiedzić model danych). Dwa decode
instrukcje używają tej wygenerowanej liczby, aby dopasować nazwę kolumny i wartość - uruchom samodzielnie wewnętrzny wybór, aby zobaczyć, jak to wygląda.
Bez uciekania się do dynamicznego SQL, nie możesz uciec od konieczności wylistowania kolumn - tylko raz z prawdziwym unpivot
, ale dwa razy z fałszywą wersją 10g i musisz upewnić się, że pasują prawidłowo i że generator numerów wierszy generuje wystarczającą liczbę wartości. (Zbyt wiele i możesz uzyskać dziwne wyniki, ale ponieważ wszelkie dodatkowe wartości będą tutaj puste, a używasz avg
, w tym przypadku nie ma to większego znaczenia; tak jak w przypadku sprawdzenia zdrowia psychicznego, prawdopodobnie i tak powinieneś dokładnie dopasować).
Lub inna wersja, oparta na tym, że zawsze chcesz mieć wszystkie kolumny oprócz name
, co oznacza, że wystarczy tylko raz wymienić potrzebne kolumny i łatwiej jest je dopasować wizualnie — po prostu dodawaj when
klauzule; i nie potrzebujesz liczby wierszy:
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