我试图在此列表中找到一些重叠数据。
我无法将此归为一类。
如何获得如下所示的结果?
表格中的数据:
PLAN_MIN PLAN_MAX
220554 229079
220554 229079
2210A5 2210A5
2210A8 2210A8
2220A5 2220A5
2220A8 2220A8
2230A5 2230A5
2230A8 2230A8
260554 267566
2610A5 2610A5
2610A8 2610A8
2620A5 2620A5
2620A8 2620A8
结果:
PLAN_MIN PLAN_MAX PLAN_MIN_1 PLAN_MAX_1
2210A5 2210A5 220554 229079
2210A8 2210A8 220554 229079
2220A5 2220A5 220554 229079
2220A8 2220A8 220554 229079
2230A5 2230A5 220554 229079
2230A8 2230A8 220554 229079
2610A5 2610A5 260554 267566
2610A8 2610A8 260554 267566
2620A5 2620A5 260554 267566
2620A8 2620A8 260554 267566
create table plan_details
(PLAN_MIN varchar2(20)
,PLAN_MAX varchar2(20)
);
insert into plan_details values ('220554','229079' );
insert into plan_details values ('2210A5','2210A5' );
insert into plan_details values ('2210A8','2210A8' );
insert into plan_details values ('2220A5','2220A5' );
insert into plan_details values ('2220A8','2220A8' );
insert into plan_details values ('2230A5','2230A5' );
insert into plan_details values ('2230A8','2230A8' );
insert into plan_details values ('260554','267566' );
insert into plan_details values ('2610A5','2610A5' );
insert into plan_details values ('2610A8','2610A8' );
insert into plan_details values ('2620A5','2620A5' );
insert into plan_details values ('2620A8','2620A8' );
commit;
答案 0 :(得分:2)
这是我的方法。每条记录将分配给一个组,指定它所属的“组”。在您的示例中,有两个组。这些组不会重叠,但它们中的行会重叠。
如何找到群组?好吧,一个小组从plan_min
值与其他任何内容不重叠的地方开始。然后它继续 - 但不包括 - 计划最小值不重叠的下一行。
因此,以下查询将查找组的起始位置。然后它会计算累积总和来计算组。最后的查询执行join
和簿记以获取您请求的格式的数据:
with groups as (
select pd.*, sum(isbegin) over (order by plan_min) as grp
from (select pd.*,
(select (case when count(*) = 0 then 1 else 0 end)
from plan_details pd2
where pd2.plan_min < pd.plan_min and
pd2.plan_max > pd.plan_min
) as IsBegin
from plan_details pd
) pd
)
select g.plan_min, g.plan_max, gg.min_plan_min, gg.max_plan_max
from groups g join
(select grp, min(plan_min) as min_plan_min,
max(plan_max) as max_plan_max
from groups
group by grp
) gg
on g.grp = gg.grp;
这已经在你的SQL小提琴上测试过,所以你可以在那里试试。
编辑:
这是OP的最终答案:
SELECT a.plan_min as plan_min, a.plan_max as plan_max , b.plan_min as range_min,
b.plan_max as range_max
FROM (SELECT p.*, row_number() OVER (ORDER BY plan_min, plan_max) rnum
FROM plan_details p
) a,
(SELECT p.*, row_number() OVER (ORDER BY plan_min, plan_max) rnum
FROM plan_details p
) b
WHERE a.rnum <> b.rnum AND
(a.plan_min between b.plan_min and b.plan_max OR
a.plan_max between b.plan_min and b.plan_max
)
ORDER BY 1,2,3,4;
答案 1 :(得分:1)
我把它当作一个谜语。您可以使用此查询获得问题中显示的结果:
select x.PLAN_MIN, x.PLAN_MAX
, (select max(PLAN_MIN) from PLAN_DETAILS
where PLAN_MIN <= substr(x.PLAN_MIN,1,4)
and PLAN_MIN not like '%A%'
) as PLAN_MIN_1
, (select max(PLAN_MAX) from PLAN_DETAILS
where PLAN_MIN <= substr(x.PLAN_MIN,1,4)
and PLAN_MIN not like '%A%'
) as PLAN_MAX_1
from PLAN_DETAILS x
where x.PLAN_MIN like '%A%'
order by 1, 2;