programing

최신 레코드를 제외한 모든 레코드를 삭제하시겠습니까?

elecom 2023. 7. 7. 18:35
반응형

최신 레코드를 제외한 모든 레코드를 삭제하시겠습니까?

일대일 관계의 DB 테이블이 두 개 있습니다.데이터는 다음과 같습니다.

select * from student, application

결과 집합:

+-----------+---------------+---------------------+
| StudentID | ApplicationID | ApplicationDateTime |
+-----------+---------------+---------------------+
| 1         | 20001         | 12 April 2011       |
| 1         | 20002         | 15 May 2011         |
| 2         | 20003         | 02 Feb 2011         |
| 2         | 20004         | 13 March 2011       |
| 2         | 20005         | 05 June 2011        |
+-----------+---------------+---------------------+

저는 가장 최근의 애플리케이션을 제외한 모든 애플리케이션을 삭제하고 싶습니다.다시 말해, 각 학생은 하나의 애플리케이션만 연결해야 합니다.위의 예를 사용하면 데이터는 다음과 같습니다.

+-----------+---------------+---------------------+
| StudentID | ApplicationID | ApplicationDateTime |
+-----------+---------------+---------------------+
| 1         | 20002         | 15 May 2011         |
| 2         | 20005         | 05 June 2011        |
+-----------+---------------+---------------------+

올바른 기록을 걸러내기 위해 DELETE 문을 구성하려면 어떻게 해야 합니까?

DELETE FROM student
WHERE ApplicationDateTime <> (SELECT max(ApplicationDateTime) 
                              FROM student s2
                              WHERE s2.StudentID  = student.StudentID)

의견에 대한 긴 토론을 고려할 때 다음 사항에 유의하십시오.

의 명령문은 명령문이 실행되는 동안 테이블의 변경 사항에 관계없이 명령문 수준 읽기 일관성을 적절하게 구현하는 모든 데이터베이스에서 작동합니다.

표를 동시에 수정하더라도 올바르게 작동하는 데이터베이스:Oracle(이 질문에 대한 내용), Postgres, SAP HANA, Firebird(대부분 InnoDB를 사용하는 MySQL).모두 문이 시작된 시점에서 데이터의 일관된 보기를 보장하기 때문입니다.변경 내용<>로.<고객을 위해 아무것도 변경하지 않습니다(이 질문에 대한 Oracle 포함).

위에서 언급한 데이터베이스의 경우 팬텀 읽기 또는 반복할 수 없는 읽기는 단일 문 내에서가 아니라 여러 문 사이에서만 발생할 수 있기 때문에 문은 분리 수준의 영향을 받지 않습니다.

MVCC를 제대로 구현하지 않고 잠금에 의존하여 동시 쓰기 액세스를 관리하는 데이터베이스의 경우 테이블이 동시에 업데이트되면 실제로 잘못된 결과가 발생할 수 있습니다.다음을 사용하여 해결할 경우<아마도 필요할 것입니다.

사용할 수 있습니다.row_number()(또는)rank()또는dense_rank()아니면 심지어 그냥.rownum순서를 레코드에 적용한 다음 해당 순서를 사용하여 삭제할 항목을 결정합니다.이 경우, 다음과 같이 주문합니다.applicationdatetime desc각 학생의 가장 최근 날짜가 있는 응용 프로그램에 1:

select studentid, applicationid from (
    select studentid, applicationid,
        row_number() over (partition by studentid
            order by applicationdatetime desc) as rn
    from application
)
where rn = 1;

 STUDENTID APPLICATIONID
---------- -------------
         1         20002
         2         20005

그런 다음 순위가 1보다 높은 모든 항목을 삭제할 수 있습니다. 그러면 중요한 레코드가 보존됩니다.

delete from application
where (studentid, applicationid) in (
    select studentid, applicationid from (
        select studentid, applicationid,
            row_number() over (partition by studentid
                order by applicationdatetime desc) as rn
        from application
    )
    where rn > 1
);

3 rows deleted.

처음에는 그렇게 할 수 있습니다.

DELETE FROM [student]
           or [application]
WHERE (studentid, applicationid) NOT IN (SELECT StudentID
                                               ,MAX(ApplicationID)
                                         FROM student
                                             ,application
group by StudentID);

그러나 테이블에 있는 모든 레코드를 삭제하고 테이블에서 최대값을 선택하여 데이터(원하는 항목)를 삽입한 후 백업 테이블을 만들 수 있는 또 다른 솔루션이 있습니다.

언급URL : https://stackoverflow.com/questions/7238983/delete-all-records-except-the-most-recent-one

반응형