数据库: Oracle数据库12c版本12.2.0.1.0
以下是我的测试用例脚本:
create table test
(
id number(1),
sdate date,
tdate date,
prnt_id number(1)
);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('10/17/2012','mm/dd/yyyy'), to_date('10/16/2014','mm/dd/yyyy'), 2);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('10/16/2014','mm/dd/yyyy'), to_date('2/16/2016','mm/dd/yyyy'), 2);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('2/16/2016','mm/dd/yyyy'), to_date('9/30/2016','mm/dd/yyyy'), 3);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('9/30/2016','mm/dd/yyyy'), to_date('3/16/2017','mm/dd/yyyy'), 3);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('3/16/2017','mm/dd/yyyy'), to_date('1/16/2019','mm/dd/yyyy'), 2);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('1/16/2019','mm/dd/yyyy'), to_date('10/16/2019','mm/dd/yyyy'), 2);
insert into test (id, sdate, tdate, prnt_id) values (1, to_date('10/16/2019','mm/dd/yyyy'), to_date('12/1/2999','mm/dd/yyyy'), 2);
commit;
select * from test order by sdate;问题:
我想修改上面的Select SQL,它返回测试表中的所有7行,选择所有列加上另外两列。第一个附加列(min_sdate)将为第1,2行返回10/17/2012,为第3,4行返回2/16/2016,为第5,6,7行返回3/16/2017。第二个附加列(max_tdate)将为第1,2行返回2/16/2016,为第3,4行返回3/16/2017,为第5,6,7行返回12/1/2999。基本上,我尝试按prnt_id列分组,但不是两个组(prnt_id: 2和3),我想要三个组(prnt_id: 2,3,2)。然后,对于这三个组,得到min(sdate)和max(tdate)。我想我可以使用带有window子句的分析函数min()和max()来实现这一点,但不确定如何构建SQL。
任何或所有的帮助都将不胜感激。谢谢!
发布于 2020-03-26 03:13:36
这是一种缝隙和岛屿的形式。假设日期块没有间隙,您可以使用行号的差异来标识岛:
select t.*,
min(sdate) over (partition by id, prnt_id, seqnum - seqnum_2),
max(edate) over (partition by id, prnt_id, seqnum - seqnum_2)
from (select t.*,
row_number() over (partition by id order by sdate) as seqnum,
row_number() over (partition by id, prnt_id order by sdate) as seqnum_2
from test t
) t;为什么这样做有点难以解释。但是,如果您查看子查询的结果,您将能够看到行号的差异如何定义您想要定义的组。
https://stackoverflow.com/questions/60855617
复制相似问题