我需要有关oracle SQL的帮助。表中的数据如下所示。 对于给定的数据,我需要根据COB日期范围和值创建一个波段。
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
有人可以帮忙吗?
答案 0 :(得分:7)
lag and lead是你的朋友
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
编辑:修复查询:)
Rob van Wijk编辑:以下是查询有效的证明:
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.
答案 1 :(得分:0)
在伪代码中,可以使用以下内容完成:
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