简体   繁体   中英

Oracle SQL: Transpose Columns to Rows

There have been some questions on this but I couldn't find a relevant result for me. I have a query that gives me 2 columns of results:

 Day            Tot_dLS   
 01-Sep-12      10000
 02-Sep-12      9920

I want to transpose the Date so it reads:

01-Sep-12    02-Sep-12 
10000         9920

Is this possible?

Not really with a SQL query, since the same column would have to contain two different data types. You can get by with some tricks (casting everything to string) - but such things are much better done in the presentation application, or report, itself, than from the query.

Since you can return a fixed number of columns and you can use generic column names, you can do a standard pivot query

SELECT max( case when rn = 1 then tot_dls else null end ) col_1,
       max( case when rn = 2 then tot_dls else null end ) col_2,
       max( case when rn = 3 then tot_dls else null end ) col_3,
       <<25 more>>
       max( case when rn = 29 then tot_dls else null end ) col_29,
       max( case when rn = 30 then tot_dls else null end ) col_30
  FROM (SELECT day,
               tot_dls,
               rank() over (order by day) rn
          FROM your_table
         WHERE day between date '2012-09-01' 
                       and date '2012-09-02' -- Use whatever criteria you want here
       )

This code:

create table your_table(day date, tot_dls number(5));
insert into your_table values ('01-SEP-2012',10000);
insert into your_table values ('02-SEP-2012',9920);
insert into your_table values ('03-SEP-2012',12020);
insert into your_table values ('04-SEP-2012',11030);

column dummy noprint
column "Header" format a7
column "Data"   format a60
set hea off
SELECT 0 DUMMY
      ,'Day'                                      "Header"
      ,LISTAGG(' ' || TO_CHAR(Day,'DD-MON-YYYY')) WITHIN GROUP (ORDER BY Day) "Data"
FROM  your_table
UNION
SELECT 1
      ,'Tot_dls'
      ,LISTAGG(LPAD(TOT_DLS,13-LENGTH(TO_CHAR(TOT_DLS,'FM')),' ')) WITHIN GROUP (Order by Day)
FROM your_table
ORDER by 1;

produces this output using SQL*Plus on an Oracle 11g (11.2.0) database.

Day      01-SEP-2012 02-SEP-2012 03-SEP-2012 04-SEP-2012
Tot_dls        10000        9920       12020       11030

You can use CASE statements and an aggregate to perform this. You can use something like this:

select max(case when day = '01-Sep-12' then Tot_dLS end) "01-Sep-12",
       max(case when day = '02-Sep-12' then Tot_dLS end) "02-Sep-12",
       ........ add more columns here
from yourtable

then this would be expanded on to add more columns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM