Als je op 11G zat, zou je 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
Maar aangezien je dat niet bent, kun je het faken. Aanpassing van deze 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
In beide gevallen is de binnenste select
zet rijen om in kolommen; in 10g moet je het gewoon zelf doen. De SELECT ... CONNECT BY ...
genereert gewoon een lijst met dummy-waarden, en dit moet voldoende zijn om het aantal kolommen te dekken dat u naar rijen converteert (en als u er echt 1000 heeft, moet u het gegevensmodel echt opnieuw bekijken). De twee decode
instructies gebruiken dat gegenereerde nummer om een kolomnaam en waarde te matchen - voer de inner select alleen uit om te zien hoe dat eruit ziet.
Zonder toevlucht te nemen tot dynamische SQL, ontkom je er niet aan om de kolommen op te sommen - slechts één keer met de echte unpivot
, maar twee keer met de nep 10g-versie, en je moet ervoor zorgen dat ze goed overeenkomen en dat de rijnummergenerator voldoende waarden produceert. (Te veel en je krijgt misschien vreemde resultaten, maar omdat eventuele extra waarden hier nul zijn en je avg
gebruikt , in dit geval maakt het niet zoveel uit; net als een gezond verstand moet je het waarschijnlijk toch precies overeenkomen).
Of een andere versie, gebaseerd op het feit dat je altijd alle kolommen wilt hebben behalve name
, wat betekent dat u de kolommen die u wel wilt slechts één keer hoeft op te sommen en het gemakkelijker is om ze visueel op elkaar af te stemmen - blijf gewoon when
toevoegen clausules; en je hebt het aantal rijen niet nodig:
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