sql >> Database >  >> RDS >> Oracle

Oracle10G SQL:kolommen in rijen veranderen

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



  1. Mogelijke injectie vanaf datumreeks Selecteer zoekopdracht

  2. Hoe koppel ik lift en MySQL?

  3. 13 blogartikelen over best practices en tips voor databaseontwerp

  4. mysql like% query is traag met full-text index