Skip to Main Content
  • Questions
  • Transposing the data from rows to columns and to split the columns into new line during particular data intervals

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, KUMAR.

Asked: June 27, 2016 - 5:55 pm UTC

Last updated: June 29, 2016 - 7:35 pm UTC

Version: oracle 11g

Viewed 1000+ times

You Asked

Hi Tom,

Can you suggest me the solution for transposing the data from rows to columns, and to split the data into new column during particular interval.

Here is the sample tables and data that i am working on and the desired output as well:

I am using two tables as the below structure

CREATE TABLE TEST1 (
READING NUMBER, TIME VARCHAR2(50), VALUE VARCHAR2(50) );

CREATE TABLE TEST2 (
READING NUMBER, TIME1 VARCHAR2(50), VALUE1 VARCHAR2(50), TIME2 VARCHAR2(50), VALUE2 VARCHAR2(50), TIME3 VARCHAR2(50), VALUE3 VARCHAR2(50), TIME4 VARCHAR2(50), VALUE4 VARCHAR2(50), TIME5 VARCHAR2(50), VALUE5 VARCHAR2(50), TIME6 VARCHAR2(50), VALUE6 VARCHAR2(50), TIME7 VARCHAR2(50), VALUE7 VARCHAR2(50) );

And the data in test1 table is:

insert into TEST1 (READING, TIME, VALUE)
with somedata as
(
select 123, '08:30', '1.0' from dual
union all
select 123, '15:30', '2.0' from dual
union all
select 123, '23:30', '2.5' from dual
union all
select 123, '00:00', '3.0' from dual
union all
select 123, '10:30', '3.5' from dual
union all
select 123, '00:00', '4.0' from dual
union all
select 123, '14:30', '5.0' from dual
union all
select 123, '21:30', '6.0' from dual
)
select * from somedata ;

Finally, the desired output in TEST2 table have to look like:

READING TIME1 VALUE1 TIME2 VALUE2 TIME3 VALUE3 TIME4 VALUE4 TIME5 VALUE5 TIME6 VALUE6 TIME7 VALUE7
123 08:30 1.0 15:30 2.0 23:30 2.5
123 00:00 3.0 10:30 3.5
123 00:00 4.0 14:30 5.0 21:30 6.0

As i requested, the column have to be split into new line whenever the "Time" field has 00:00

Can you please help me with the solution for this.

and Chris said...

The basic approach I've taken is:

- Assign each time range a group. A new group starts when t = 00:00
- Number the rows within the group, according to the time
- Pivot the results to get the output you want

create table test1
  (
    reading number, time varchar2 ( 50 ) , value varchar2 ( 50 )
  ) ;
insert into test1
    ( reading, time, value
    )
with somedata as
  ( select 123, '08:30', '1.0' from dual
  union all
  select 123, '15:30', '2.0' from dual
  union all
  select 123, '23:30', '2.5' from dual
  union all
  select 123, '00:00', '3.0' from dual
  union all
  select 123, '10:30', '3.5' from dual
  union all
  select 123, '00:00', '4.0' from dual
  union all
  select 123, '14:30', '5.0' from dual
  union all
  select 123, '21:30', '6.0' from dual
  )
select * from somedata ;

select *
from
  (select s.reading, time, value,
    dense_rank ( ) over ( order by lv ) g, 
    row_number ( ) over ( partition by lv order by value ) rn
  from
    (select s.*, last_value ( t ) ignore nulls over ( order by value ) lv
    from
      (select reading, time, value,
        case
          when time = '00:00'
          or rownum = 1 then rownum
        end t
      from test1
      ) s
    ) s
  ) pivot ( min ( time ) as time, min ( value ) as val 
    for ( rn ) in ( 1 as "1", 2 as "2", 3 as "3" ) )
order by g;

   READING          G 1_TIM 1_V 2_TIM 2_V 3_TIM 3_V
---------- ---------- ----- --- ----- --- ----- ---
       123          1 08:30 1.0 15:30 2.0 23:30 2.5
       123          2 00:00 3.0 10:30 3.5          
       123          3 00:00 4.0 14:30 5.0 21:30 6.0

I'm sure there are more concise ways of writing this.

Some other thoughts:

- If you need more columns, just add more to the for clause of the pivot
- How do you know which order to process the times? Is this part of a date, or are you relying on the values to increase? If so, how will you know if they don't?

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

tolupuluri, June 29, 2016 - 7:49 pm UTC

Thank you for your response Tom.

Let me try with the solution you had given and to modify according to my requirement.

And the time is the part of the date value.


More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.