transpose column to row oracle

前端 未结 2 374
粉色の甜心
粉色の甜心 2021-01-07 09:20

I have a query returned value in this form (query return more than 50 columns).

 1-99transval  100-200transval  200-300transval ... 1-99nontransval 100...
           


        
2条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-07 10:06

    In pure SQL, it will need a lot of coding because you will have to manually put the range as there is no relation between the values and the range at all. Had there been a relationship, you could use CASE expression and build the range dynamically.

    SQL> WITH DATA AS
      2    (SELECT 50 "1-99transval",
      3      90 "100-200transval",
      4      80 "200-300transval",
      5      67 "1-99nontransval",
      6      58 "100-200nontransval",
      7      88 "200-300nontransval"
      8    FROM dual
      9    )
     10  SELECT '1-99' range,
     11    "1-99transval" transval,
     12    "1-99nontransval" nontransval
     13  FROM DATA
     14  UNION
     15  SELECT '100-200' range,
     16    "100-200transval",
     17    "100-200nontransval" nontransval
     18  FROM DATA
     19  UNION
     20  SELECT '200-300' range,
     21    "200-300transval",
     22    "200-300nontransval" nontransval
     23  FROM DATA;
    
    RANGE     TRANSVAL NONTRANSVAL
    ------- ---------- -----------
    1-99            50          67
    100-200         90          58
    200-300         80          88
    

    From Oracle database 11g Release 1 and above, you could use UNPIVOT

    SQL> WITH DATA AS
      2    (SELECT 50 "1-99transval",
      3      90 "100-200transval",
      4      80 "200-300transval",
      5      67 "1-99nontransval",
      6      58 "100-200nontransval",
      7      88 "200-300nontransval"
      8    FROM dual
      9    )
     10  SELECT *
     11  FROM   DATA
     12  UNPIVOT( (transval,nontransval)
     13  FOR RANGE IN ( ("1-99transval","1-99nontransval") AS '1-99'
     14                ,("100-200transval","100-200nontransval") AS '100-200'
     15                ,("200-300transval","200-300nontransval") AS '200-300'));
    
    RANGE     TRANSVAL NONTRANSVAL
    ------- ---------- -----------
    1-99            50          67
    100-200         90          58
    200-300         80          88
    

    Above, in your case you need to replace the WITH clause with your existing query as a sub-query. You need to include other columns in the UNION.

    In PL/SQL, you could (ab)use EXECUTE IMMEDIATE and get the "range" by extracting the column names in dynamic sql.

    Although, it would be much better to modify/rewrite your existing query which you have not shown yet.

提交回复
热议问题