Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle10G SQL:Spalten in Zeilen umwandeln

Wenn Sie 11G verwenden, können Sie 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

Aber da Sie es nicht sind, können Sie es vortäuschen. Anpassung von dieser Website :

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 beiden Fällen das innere select wandelt Zeilen in Spalten um; in 10g musst du es nur selber machen. Der SELECT ... CONNECT BY ... generiert nur eine Liste von Dummy-Werten, und diese muss ausreichen, um die Anzahl der Spalten abzudecken, die Sie in Zeilen konvertieren (und wenn Sie wirklich 1000 haben, sollten Sie das Datenmodell wirklich noch einmal besuchen). Die beiden decode -Anweisungen verwenden diese generierte Zahl, um einen Spaltennamen und -wert abzugleichen - führen Sie die innere Auswahl selbst aus, um zu sehen, wie das aussieht.

Ohne auf dynamisches SQL zurückzugreifen, kommt man um das Auflisten der Spalten nicht herum - nur einmal mit dem echten unpivot , aber zweimal mit der gefälschten 10g-Version, und Sie müssen sicherstellen, dass sie richtig übereinstimmen und dass der Zeilennummerngenerator genügend Werte erzeugt. (Zu viele und Sie könnten ungerade Ergebnisse erhalten, aber da alle zusätzlichen Werte hier null sind und Sie avg verwenden , es spielt in diesem Fall keine große Rolle; Nur als Plausibilitätsprüfung sollten Sie wahrscheinlich sowieso genau übereinstimmen).

Oder eine andere Version, basierend darauf, dass Sie immer alle Spalten außer name wollen , was bedeutet, dass Sie die gewünschten Spalten nur einmal auflisten müssen und es einfacher ist, sie visuell abzugleichen - fügen Sie einfach immer wieder when hinzu Klauseln; und Sie brauchen die Zeilenanzahl nicht:

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