2017-12-28 26 views
0

테이블에서 중복 된 (부분) 삭제에 도와 주시겠습니까? 다섯 개의 열이 포함 된 표가 있습니다. 그리고이 표에는 복제본이 있습니다. 단 4 개의 열만 같고 하나의 열 (field5)이 다릅니다. 즉,오라클 SQL - 환경 설정으로 부분 복제본을 삭제하는 방법

F1 F2 F3 F4 F5 
A1 A2 A3 A4 103 
A1 A2 A3 A4 3 

따라서 복제본의 경우 5 열을 제외하고는 4 열/필드가 동일합니다. 그리고 "103"이라는 숫자가 포함 된 행을 지우고 싶습니다. 이것을 어떻게 할 수 있습니까?

정상적인 복제본이라면 max (rowid)를 사용하고 해당 행을 제거하면됩니다. 하지만 이제는 더 높은 숫자 대신 낮은 숫자가 포함 된 행을 삭제할 수 있습니다.

내가 생각할 수있는 한 가지 방법은 중복 된 행을 포함하는 새 테이블을 만드는 것입니다. Field5는이 테이블에서 더 높은 번호를 갖습니다. 그런 다음이 새 테이블과 비교하여 원본 테이블에서 행을 삭제합니다. 하지만 그게 나에게 좋은 해결책이 아닌 것 같습니다. 특히 원본 테이블이 크다면 시간이 오래 걸릴 수 있습니다.

도움을 주시면 감사하겠습니다. 고맙습니다.

답변

1

아이디어는 F1,F2,F3,F4의 각 조합에 대한 기록을 유지하고 나머지는 삭제하는 것입니다.

이 시도 :이 방법에 대해

DELETE FROM TABLE_NAME WHERE ROWID IN 
    (SELECT ROWID FROM 
     (SELECT ROWID, row_number() OVER(PARTITION BY F1,F2,F3,F4 ORDER BY F5) RN 
      FROM TABLE_NAME) 
    WHERE RN<>1); 
+1

ORA-01446 : DISTINCT, GROUP BY 등에서 ROWID를 선택하거나 샘플을 선택할 수 없습니다. 그러나 ROWNUM을 제거하면 작동합니다. – Littlefoot

+0

게시물에 대해 감사드립니다. 이것은 완벽하게 작동합니다. 이전 게시물에서 Littlefoot가 지정한 오류가 발생했습니다. 내가 선택할 수 있다면, 이것은 나를위한 최상의 해결책이 될 것입니다 :) –

0

를?

SQL> select * from test order by f1, f5; 

F1 F2 F3 F4   F5 
-- -- -- -- ---------- 
a1 a2 a3 a4   3 
a1 a2 a3 a4   50 --> delete 
a1 a2 a3 a4  103 --> delete 
b1 b2 b3 b4   2 
b1 b2 b3 b4  200 --> delete 
c1 c2 c3 c4   1 

6 rows selected. 

SQL> delete from test t 
    2  where rowid not in (select rowid 
    3        from test t1 
    4        where  t1.f1 = t.f1 
    5         and t1.f2 = t.f2 
    6         and t1.f3 = t.f3 
    7         and t1.f4 = t.f4 
    8         and t1.f5 = 
    9           (select min (t2.f5) 
10            from test t2 
11           where  t2.f1 = t.f1 
12             and t2.f2 = t.f2 
13             and t2.f3 = t.f3 
14             and t2.f4 = t.f4)); 

3 rows deleted. 

SQL> select * from test order by f1, f5; 

F1 F2 F3 F4   F5 
-- -- -- -- ---------- 
a1 a2 a3 a4   3 
b1 b2 b3 b4   2 
c1 c2 c3 c4   1 

SQL> 
+0

고마워요 Littlefoot! 당신의 대답은 훌륭합니다! 첫 번째 게시물에서 문제를 지적 해 주셔서 감사합니다. 나는 이것이 내가 스스로 알고있는 물건/개념에 의해 해결 될 수 있다는 것을 몰랐다. :) 그런 해결책을 지적 해 주셔서 감사합니다. 이 솔루션에 대한 단점은 테이블에 많은 열이있을 때 비트가 너무 많다는 것입니다. –

0

나는 일반적으로 그냥 이렇게 :

입니다
delete demo 
where rowid in 
     (select lead(rowid) over (partition by f1, f2, f3, f4 order by f5) as next_rowid 
     from demo); 

, 그 (f1, f2, f3, f4) 그룹 내 f5의 순서로 모든 "다음"행을 삭제합니다.

+0

답변 해 주셔서 감사합니다. 그것은 흥미로운 해결책입니다. 사실 처음에는 의심의 여지가 있었지만 예상대로 작동하는 것 같습니다. –