2014-01-22 2 views
0

이 목록에서 중복되는 데이터를 찾으려고합니다.목록에서 중복 데이터 찾기

그룹화 할 방법이 없습니다.

아래와 같이 결과를 얻으려면 어떻게해야합니까? 테이블에

데이터 :

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; 
+1

정확히 어떻게 당신이 알고 않을 때 "plan_min_1"및 최종 결과에 "plan_max_1"변화? 이 모든 값은 엄격하게 숫자입니까? 다른 사람은 그 안에 "A"가 있습니까? – Gerrat

+0

[so]에 오신 것을 환영합니다. 아직 시도한 것이 있습니까? 그렇다면 여기에 언급하여 문제가 무엇인지 설명하십시오. 그렇게하면 더 나은 응답을 얻을 수 있습니다. –

답변

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 바이올린에서 테스트되었습니다.

편집 :

이는 영업 이익의 최종 답변입니다 :

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; 
+0

SQL Fiddle에 관해 알려 주셔서 감사합니다. 이것은 MySQL만을위한 것입니까? 오라클 쿼리를 테스트하는 방법을 알려주시겠습니까? – user3225032

+0

@ user3225032 . . SQL Fiddle을 사용하면 Oracle, SQL Server, MySQL, SQLite 및 Postgres를 테스트 할 수 있습니다. 대단하네요! –

+0

나중에 SQL 피들은 훌륭합니다. 이것은 내가 쓴 쿼리입니다 - 페이지를 선택합니다 ( 로 range_max로부터 b.plan_max, a.plan_max range_min 로 plan_max , b.plan_min로, plan_min 로 a.plan_min SELECT * , BY ROW_NUMBER() OVER (ORDER. plan_min, plan_max) PLAN_DETAILS 피 )는, (p SELECT FROM rnum . * , plan_min BY ROW_NUMBER() OVER (ORDER, plan_max) B PLAN_DETAILS 피 ) FROM rnum WHERE a.rnum <> b.rnum AND (b.plan_min과 b.plan_max 사이의 a.plan_min) OR b.plan_min과 b.plan_max 사이의 a.plan_max )ORDER BY 1,2,3,4; – user3225032

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;