Pokud jste byli na 11G, mohli byste použít 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 protože nejste, můžete to předstírat. Adaptace z tohoto webu :
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
V obou případech vnitřní select
převádí řádky na sloupce; v 10g si to prostě musíte udělat sami. SELECT ... CONNECT BY ...
pouze vygeneruje seznam fiktivních hodnot, a ten musí mít dostatek, aby pokryl počet sloupců, které převádíte na řádky (a pokud jich máte opravdu 1000, měli byste datový model opravdu znovu navštívit). Dva decode
příkazy používají toto vygenerované číslo k porovnání názvu sloupce a hodnoty – spusťte samotný vnitřní výběr, abyste viděli, jak to vypadá.
Bez použití dynamického SQL se nemůžete zbavit nutnosti vypisovat sloupce – pouze jednou se skutečným unpivot
, ale dvakrát s falešnou 10g verzí a musíte se ujistit, že se správně shodují a že generátor čísel řádků produkuje dostatečné hodnoty. (Příliš mnoho a můžete získat divné výsledky, ale protože všechny nadbytečné hodnoty zde budou nulové a vy používáte avg
, na tom v tomto případě příliš nezáleží; stejně jako pro kontrolu zdravého rozumu byste to pravděpodobně měli stejně přesně nastavit).
Nebo jinou verzi založenou na tom, že chcete vždy všechny sloupce kromě name
, což znamená, že stačí uvést sloupce, které chcete, pouze jednou a je snazší je vizuálně sladit – stačí přidávat when
doložky; a nepotřebujete počet řádků:
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