1

I need help with oracle SQL. The data in the table is as given below.' For given data I need to create a bands based on COB dates range and Values.

COB         VALUE   
-----------------   
4/5/2012    20      
4/6/2012    20      
4/7/2012    22      
4/8/2012    21      
4/9/2012    20      
4/10/2012   21      
4/11/2012   21      
4/12/2012   22      
4/13/2012   20      

The output I am expecting is as given below:            

START_DT    END_DT          VALUE
----------------------------------  
4/5/2012    4/7/2012    20  
4/7/2012    4/8/2012    22  
4/8/2012    4/9/2012    21  
4/9/2012    4/10/2012   20  
4/10/2012   4/12/2012   21  
4/12/2012   4/13/2012   22  
4/13/2012   null        20  

Can someone help please?

2 Answers 2

7

lag and lead are your friends in this case

select cob start_dt
,      lead(cob) over (order by cob) end_dt
,      value
from
(
    select cob
    ,      value
    ,      lag(value) over (order by cob) prev_value
    from   tmp
)
where prev_value is null
or    value <> prev_value

edit: fixed query :)

Edit by Rob van Wijk: here is some proof that the query works:

SQL> create table mytable(cob,value)
  2  as
  3  select date '2012-04-05', 20 from dual union all
  4  select date '2012-04-06', 20 from dual union all
  5  select date '2012-04-07', 22 from dual union all
  6  select date '2012-04-08', 21 from dual union all
  7  select date '2012-04-09', 20 from dual union all
  8  select date '2012-04-10', 21 from dual union all
  9  select date '2012-04-11', 21 from dual union all
 10  select date '2012-04-12', 22 from dual union all
 11  select date '2012-04-13', 20 from dual
 12  /

Table created.

SQL> select cob start_dt
  2  ,      lead(cob) over (order by cob) end_dt
  3  ,      value
  4  from
  5  (   select cob
  6      ,      value
  7      ,      lag(value) over (order by cob) prev_value
  8      from   mytable
  9  )
 10  where prev_value is null
 11  or    value <> prev_value
 12  /

START_DT            END_DT                   VALUE
------------------- ------------------- ----------
05-04-2012 00:00:00 07-04-2012 00:00:00         20
07-04-2012 00:00:00 08-04-2012 00:00:00         22
08-04-2012 00:00:00 09-04-2012 00:00:00         21
09-04-2012 00:00:00 10-04-2012 00:00:00         20
10-04-2012 00:00:00 12-04-2012 00:00:00         21
12-04-2012 00:00:00 13-04-2012 00:00:00         22
13-04-2012 00:00:00                             20

7 rows selected.
Sign up to request clarification or add additional context in comments.

Comments

0

In pseudo-code it can be done with something like this:

startDate = min(COB) from table
actualDate = min(COB) from table
lastDate = max(COB) from table

lastValue = value from actualDate


while actualDate <= lastDate
  actualValue = value from actualDate

  if actualValue <> lastValue
    insert in temptable startdate, actualdate, actualValue
    startdate = actualdate

  actualdate = actualdate + 1 day



insert in temptable startdate, null, actualValue

select * from temptable

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.