Oracle
 sql >> база данни >  >> RDS >> Oracle

Oracle10G SQL:Превръщане на колони в редове

Ако бяхте на 11G, можете да използвате 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

Но тъй като не сте, можете да го фалшифицирате. Адаптиране от този сайт :

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

И в двата случая вътрешният select трансформира редове в колони; в 10g просто трябва да го направите сами. SELECT ... CONNECT BY ... просто генерира списък с фиктивни стойности и това трябва да има достатъчно, за да покрие броя на колоните, които конвертирате в редове (и ако наистина имате 1000, трябва наистина да преразгледате модела на данни). Двата decode изразите използват това генерирано число, за да съпоставят име и стойност на колона - стартирайте вътрешния избор самостоятелно, за да видите как изглежда това.

Без да прибягвате до динамичен SQL, не можете да се отървете от необходимостта да изброявате колоните - само веднъж с истинския unpivot , но два пъти с фалшивата 10g версия и трябва да се уверите, че съвпадат правилно и че генераторът на номера на редове произвежда достатъчно стойности. (Твърде много и може да получите странни резултати, но тъй като всички допълнителни стойности ще бъдат нулеви тук и използвате avg , в този случай няма голямо значение; само като проверка на разума, вероятно трябва да го направите така или иначе да съвпада точно).

Или друга версия, базирана на това, че винаги искате всички колони освен name , което означава, че трябва само веднъж да посочите колоните, които искате, и е по-лесно да ги съпоставите визуално – просто продължавайте да добавяте when клаузи; и не се нуждаете от броя на редовете:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle SQL:променливи, използвани вместо имена на таблици

  2. `show create table` еквивалент в oracle sql

  3. Върнете резултатите от заявката като списък, разделен със запетая в Oracle

  4. NLS_CHARSET_DECL_LEN() Функция в Oracle

  5. Как мога да видя дали собственикът има разрешения да изпълни процедура за съхранение в Oracle